- {% if isNewFormEnabled and canEditSignalement %}
- {% include 'back/signalement/view/edit-modals/edit-procedure-demarches.html.twig' %}
+ {% if canEditSignalement %}
+ {% include 'back/signalement/view/edit-modals/edit-procedure-demarches.html.twig' %}
{% endif %}
@@ -647,7 +643,7 @@
Procédure et démarches
- {% if isNewFormEnabled and canEditSignalement %}
+ {% if canEditSignalement %}
Modifier
{% endif %}
diff --git a/templates/back/table_result.html.twig b/templates/back/table_result.html.twig
index b24377c41..ed677c7aa 100755
--- a/templates/back/table_result.html.twig
+++ b/templates/back/table_result.html.twig
@@ -68,10 +68,6 @@
- {% if not isNewFormEnabled and signalement.statut is same as(2) %}
-
- {% endif %}
{% if is_granted('ROLE_ADMIN_TERRITORY') %}
-
-
-
- Votre signalement a bien été enregistré !
-
-
- Vous allez recevoir un email de confirmation.
-
- N'oubliez pas de regarder dans vos courriers indésirables.
-
-
-
-
J'ai déposé un signalement, et maintenant ?
-
-
- Une fois réceptionné par nos services, votre signalement va être qualifié .
- Nous déterminons à quelle procédure correspond votre situation parmi quatre procédures :
- la non décence, l'infraction au RSD (règlement sanitaire départemental), l'insalubrité et la mise en sécurité.
-
- En fonction de la procédure, différents services sont impliqués et différentes
- mesures peuvent être prises.
-
-
-
- Quelle que soit la procédure, gardez les infos suivantes à l'esprit :
-
-
-
-
-
-
- Les procédures et la réalisation des travaux peuvent durer plusieurs mois,
- n'hésitez pas à mettre à jour votre dossier depuis la page de suivi.
-
-
-
-
-
- L’entretien courant du logement est de votre responsabilité.
- Veillez à garder votre logement propre et ne pas casser ni abîmer les équipements.
-
-
-
-
-
- Certains problèmes sont pris en charge par votre assurance habitation : contactez votre assureur !
-
-
-
-
-
- Dans tous les cas, vous devez payer votre loyer.
-
-
-
-
-
-
-
Les différentes procédures
-
-
-
- La procédure de non décence
-
-
- Exemple de désordres
- Partenaires éventuels
- Propriétaire averti
- Visite
- Conciliation
- Mesures possibles
-
-
-
-
-
- Exemple de désordres
-
-
- Mon logement est mal isolé
- Le bruit extérieur est très gênant, même si je ferme les fenêtres
- Je n'ai pas de douche ni de baignoire dans mon logement
-
-
-
- Partenaires éventuels
-
- SCHS, Opérateur de visite
-
- CAF ou MSA si allocataire
-
-
- Propriétaire averti
-
- Oui
-
-
- Visite
-
- Oui
-
-
- Conciliation
-
- Oui
-
-
- Mesures possibles
-
- Recours à un conciliateur de justice
-
- Intervention de l'assurance habitation
-
- Conservation des allocations de logement*
-
-
-
-
-
-
-
-
- La procédure d'infraction au RSD
-
-
- Exemple de désordres
- Partenaires éventuels
- Propriétaire averti
- Visite
- Conciliation
- Mesures possibles
-
-
-
-
-
- Exemple de désordres
-
-
- Il y a des insectes (cafards, punaises, ...) ou des rongeurs (rats, ...) dans le bâtiment
- Il y a très peu de lumière naturelle dans mon logement
- Les plafonds sont trop bas (moins de 2.20 m)
-
-
-
- Partenaires éventuels
-
- Mairie, DDT
-
- CAF ou MSA si allocataire
-
-
- Propriétaire averti
-
- Oui
-
-
- Visite
-
- Oui
-
-
- Conciliation
-
- Oui
-
-
- Mesures possibles
-
- Recours à un conciliateur de justice
-
- Lettre de mise en demeure
-
- Injonction à réaliser les travaux
-
- Contravention de 3ème classe
-
- Conservation des allocations de logement*
-
-
-
-
-
-
-
-
- La procédure d'insalubrité
-
-
- Exemple de désordres
- Partenaires éventuels
- Propriétaire averti
- Visite
- Conciliation
- Mesures possibles
-
-
-
-
-
- Exemple de désordres
-
-
- Il n'y a pas de fenêtre ni de ventilation dans mon logement
- Mon logement est en sous-sol, sans fenêtre
- Mon logement est une pièce unique de moins de 9m²
-
-
-
- Partenaires éventuels
-
- ARS, SCHS
-
- CAF ou MSA si allocataire
-
-
- Propriétaire averti
-
- Oui
-
-
- Visite
-
- Oui
-
-
- Conciliation
-
- Non
-
-
- Mesures possibles
-
- Arrêté préfectoral
-
- Travaux effectués d'office à rembourser
-
- Amende par jour de retard
-
- Suspension du loyer et des allocations de logement*
-
- Evacuation des lieux et relogement temporaire en cas de danger immédiat
-
-
-
-
-
-
-
-
- La procédure de mise en sécurité
-
-
- Exemple de désordres
- Partenaires éventuels
- Propriétaire averti
- Visite
- Conciliation
- Mesures possibles
-
-
-
-
-
- Exemple de désordres
-
-
- Le bâtiment présente un risque d'effondrement
- Le sol du logement est dangereux : il bouge et est fissuré
- Il y a beaucoup de moisissure dans toutes les pièces du logement
-
-
-
- Partenaires éventuels
-
- SCHS
-
- Mairie
-
-
- Propriétaire averti
-
- Oui
-
-
- Visite
-
- Oui
-
-
- Conciliation
-
- Non
-
-
- Mesures possibles
-
- Arrêté municipal
-
- Travaux effectués d'office à rembourser
-
- Astreinte par jour de retard
-
- Suspension du loyer et des allocations de logement*
-
- Evacuation des lieux et relogement temporaire en cas de danger immédiat**
-
-
-
-
-
-
-
- * La suspension des allocations logement concerne uniquement les allocataires.
- La CAF ou la MSA peut suspendre le versement de l'allocation logement au propriétaire, le temps de la procédure.
-
- ** Si le logement présente un danger immédiat pour la sécurité des personnes qui l'occupent,
- la mairie peut décider de mettre en place une procédure de relogement d'urgence.
-
-
-
- Qu'avez-vous pensé du service {{ platform.name }} ?
-
- Cliquez sur le bouton ci-dessous et donnez votre avis !
-
-
-
-
-
-
- {% include '_partials/_signalement_steps_tabs.html.twig' %}
-
-{% endblock %}
\ No newline at end of file
diff --git a/tests/Functional/Controller/Back/SignalementControllerTest.php b/tests/Functional/Controller/Back/SignalementControllerTest.php
index 9d447fd3e..11be34ee5 100644
--- a/tests/Functional/Controller/Back/SignalementControllerTest.php
+++ b/tests/Functional/Controller/Back/SignalementControllerTest.php
@@ -16,48 +16,6 @@ protected function setUp(): void
self::ensureKernelShutdown();
}
- /**
- * @dataProvider provideRoutesEdit
- */
- public function testSignalementEditionSuccessfullyDisplay(string $route, Signalement $signalement): void
- {
- $client = static::createClient();
- /** @var UserRepository $userRepository */
- $userRepository = static::getContainer()->get(UserRepository::class);
-
- $user = $userRepository->findOneBy(['email' => 'admin-01@histologe.fr']);
-
- $client->loginUser($user);
- $client->request('GET', $route);
-
- if (Signalement::STATUS_ACTIVE === $signalement->getStatut()) {
- $this->assertResponseIsSuccessful($signalement->getId());
- $this->assertSelectorTextContains(
- 'h1.fr-h2',
- 'Edition signalement #'.$signalement->getReference(),
- $signalement->getReference()
- );
- } else {
- $this->assertResponseRedirects('/bo/signalements/');
- }
- }
-
- public function provideRoutesEdit(): \Generator
- {
- /** @var SignalementRepository $signalementRepository */
- $signalementRepository = static::getContainer()->get(SignalementRepository::class);
- /** @var UrlGeneratorInterface $generatorUrl */
- $generatorUrl = static::getContainer()->get(UrlGeneratorInterface::class);
-
- $signalements = $signalementRepository->findAll();
-
- /** @var Signalement $signalement */
- foreach ($signalements as $signalement) {
- $route = $generatorUrl->generate('back_signalement_edit', ['uuid' => $signalement->getUuid()]);
- yield $route => [$route, $signalement];
- }
- }
-
/**
* @dataProvider provideRoutes
*/
diff --git a/tests/Functional/Controller/FrontSignalementControllerTest.php b/tests/Functional/Controller/FrontSignalementControllerTest.php
index ede2a6baa..fdd4e3a1f 100644
--- a/tests/Functional/Controller/FrontSignalementControllerTest.php
+++ b/tests/Functional/Controller/FrontSignalementControllerTest.php
@@ -7,93 +7,12 @@
use App\Tests\SessionHelper;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
-use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
class FrontSignalementControllerTest extends WebTestCase
{
use SessionHelper;
- /**
- * @dataProvider provideAdressSignalementWithTerritoryActive
- */
- public function testEnvoiSignalementFromActiveTerritory(array $adressSignalement)
- {
- $client = static::createClient();
-
- /** @var RouterInterface $router */
- $router = self::getContainer()->get(RouterInterface::class);
- $routeSignalementSend = $router->generate('front_signalement');
- $crawler = $client->request('GET', $routeSignalementSend);
- $token = $crawler->filter('input[name=_token]')->attr('value');
-
- $payload = $this->getCommonValidPayload();
- $payloadSignalement = [
- 'signalement' => array_merge($payload, $adressSignalement),
- '_token' => $token,
- ];
-
- $urlPostSignalement = $router->generate('envoi_signalement');
- $client->request('POST', $urlPostSignalement, $payloadSignalement);
-
- $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
- $bodyContent = $client->getResponse()->getContent();
- $this->assertEquals(json_decode($bodyContent, true)['response'], 'success');
- }
-
- /**
- * @dataProvider provideAdressSignalementWithTerritoryInactive
- */
- public function testEnvoiSignalementFromInactiveTerritory(array $adressSignalement)
- {
- $client = static::createClient();
-
- /** @var RouterInterface $router */
- $router = self::getContainer()->get(RouterInterface::class);
- $routeSignalementSend = $router->generate('front_signalement');
- $crawler = $client->request('GET', $routeSignalementSend);
- $token = $crawler->filter('input[name=_token]')->attr('value');
-
- $urlPostSignalement = $router->generate('envoi_signalement');
-
- $payload = $this->getCommonValidPayload();
- $payloadSignalement = [
- 'signalement' => array_merge($payload, $adressSignalement),
- '_token' => $token,
- ];
- $client->request('POST', $urlPostSignalement, $payloadSignalement);
-
- $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
- $bodyContent = $client->getResponse()->getContent();
- $this->assertEquals(json_decode($bodyContent, true)['response'], 'Territory is inactive');
- }
-
- public function testConstraintValidationSignalement()
- {
- $client = static::createClient();
-
- /** @var RouterInterface $router */
- $router = self::getContainer()->get(RouterInterface::class);
- $routeSignalementSend = $router->generate('front_signalement');
- $crawler = $client->request('GET', $routeSignalementSend);
- $token = $crawler->filter('input[name=_token]')->attr('value');
-
- $payloadSignalement = [
- 'signalement' => $this->getErrorPayload(),
- '_token' => $token,
- ];
-
- $urlPostSignalement = $router->generate('envoi_signalement');
- $client->request('POST', $urlPostSignalement, $payloadSignalement);
-
- $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
- $bodyContent = $client->getResponse()->getContent();
- $this->assertStringContainsString(
- 'formErrors',
- json_decode($bodyContent, true)['response']
- );
- }
-
public function testDisplaySuiviSignalement(): void
{
$client = static::createClient();
@@ -151,88 +70,6 @@ public function testPostUsagerResponse(): void
$this->assertResponseRedirects('/suivre-mon-signalement/'.$codeSuivi.'?from='.$emailOccupant);
}
- public function provideAdressSignalementWithTerritoryActive(): array
- {
- return [
- 'La Réunion' => [[
- 'adresseOccupant' => '45 Rue du Général de Gaulle',
- 'villeOccupant' => 'Saint-Denis',
- 'cpOccupant' => '97400',
- 'geoloc' => ['lat' => 55.452091, 'lng' => -20.885586],
- 'inseeOccupant' => '97411',
- ]],
- 'La Martinique' => [[
- 'adresseOccupant' => '4 Avenue Louis Moreau Gottschalk',
- 'villeOccupant' => 'Schoelcher',
- 'cpOccupant' => '97233',
- 'geoloc' => ['lat' => 14.616930, 'lng' => -61.086790],
- 'inseeOccupant' => '97229',
- ]],
- 'Corse du Sud' => [[
- 'adresseOccupant' => '3 Boulevard du Roi Jerome',
- 'villeOccupant' => 'Ajjacio',
- 'cpOccupant' => '20000',
- 'geoloc' => ['lat' => 41.920468, 'lng' => 8.738425],
- 'inseeOccupant' => '2A004',
- ]],
- 'Alpes Maritimes' => [[
- 'adresseOccupant' => '28 Avenue Felix Faure',
- 'villeOccupant' => 'Menton',
- 'cpOccupant' => '06500',
- 'geoloc' => ['lat' => 43.774674, 'lng' => 7.502405],
- 'inseeOccupant' => '06083',
- ]],
- 'Côte-d\'Or' => [[
- 'adresseOccupant' => '15 Rue des Godrans',
- 'villeOccupant' => 'Dijon',
- 'cpOccupant' => '21000',
- 'geoloc' => ['lat' => 47.324467, 'lng' => 5.039006],
- 'inseeOccupant' => '21231',
- ]],
- 'Bastia' => [[
- 'adresseOccupant' => '2 rue de la marine',
- 'villeOccupant' => 'Bastia',
- 'cpOccupant' => '20200',
- 'geoloc' => ['lat' => 42.70278, 'lng' => 9.45],
- 'inseeOccupant' => '2B033',
- ]],
- 'Chenelette' => [[
- 'adresseOccupant' => '7 place Ganelon',
- 'villeOccupant' => 'Chenelette',
- 'cpOccupant' => '69430',
- 'geoloc' => ['lat' => 46.166672, 'lng' => 4.48333],
- 'inseeOccupant' => '69054',
- ]],
- 'Lyon 1er arrondissement' => [[
- 'adresseOccupant' => 'Ruelle des Fantasques',
- 'villeOccupant' => 'Lyon',
- 'cpOccupant' => '69001',
- 'geoloc' => ['lat' => 45.7640, 'lng' => 4.8357],
- 'inseeOccupant' => '69381',
- ]],
- ];
- }
-
- public function provideAdressSignalementWithTerritoryInactive(): array
- {
- return [
- 'Paris' => [[
- 'adresseOccupant' => '174 Quai de Jemmapes',
- 'villeOccupant' => 'Paris',
- 'cpOccupant' => '75010',
- 'geoloc' => ['lat' => 55.452091, 'lng' => -20.885586],
- 'inseeOccupant' => '75110',
- ]],
- 'Seine et Marne' => [[
- 'adresseOccupant' => '84 Avenue Charles Rouxel',
- 'villeOccupant' => 'Pontault-Combault',
- 'cpOccupant' => '77340',
- 'geoloc' => ['lat' => 48.791284, 'lng' => 2.603893],
- 'inseeOccupant' => '77373',
- ]],
- ];
- }
-
private function getCommonValidPayload(): array
{
return [
From c52338a2952d201cf92514dbaafa34708d2c863a Mon Sep 17 00:00:00 2001
From: emilschn
Date: Tue, 5 Mar 2024 10:59:29 +0100
Subject: [PATCH 02/10] remove old formulaire from js/css #2294
---
assets/styles/histologe.scss | 31 +-
public/js/app.js | 882 +-----------------
public/js/const.js | 22 -
public/js/const.min.js | 30 -
.../Loader/LoadSignalementData.php | 8 +-
src/Form/SignalementType.php | 626 -------------
6 files changed, 8 insertions(+), 1591 deletions(-)
delete mode 100755 src/Form/SignalementType.php
diff --git a/assets/styles/histologe.scss b/assets/styles/histologe.scss
index aff9aa6ea..b3459539b 100644
--- a/assets/styles/histologe.scss
+++ b/assets/styles/histologe.scss
@@ -46,15 +46,6 @@ pre {
max-width: 100%;
}
-
-.fr-hover-critere:hover {
- background: rgba(0, 0, 145, 0.15);
-}
-
-[aria-expanded="true"] .fr-hover-critere {
- background: rgba(0, 0, 145, 0.15);
-}
-
/*STYLE*/
.fr-w-100 {
width: 100%;
@@ -138,7 +129,7 @@ pre {
background-color: rgba(191, 204, 251, 0.37);
}
-.fr-toggle--parent, .fr-accordion, .toggle-criticite, [role="button"], .fr-list--hover li, .fr-btn, .fr-checkbox-affectation__parent, .fr-checkbox-affectation__parent label {
+.fr-toggle--parent, .fr-accordion, [role="button"], .fr-list--hover li, .fr-btn, .fr-checkbox-affectation__parent, .fr-checkbox-affectation__parent label {
cursor: pointer !important;
user-select: none;
}
@@ -148,11 +139,6 @@ pre {
background-color: var(--background-alt-grey);
}
-.toggle-criticite:hover {
- border-radius: .25rem;
- background-color: white;
-}
-
.fr-rounded {
border-radius: .25rem;
}
@@ -388,21 +374,6 @@ a.fr-btn.fr-btn--icon-left.fr-fi-file-pdf-fill.ignore-blank-style::before {
resize: vertical;
}
-.toggle-criticite > input[type="radio"] {
- width: 60px;
- height: 50px;
- position: relative;
-}
-
-.toggle-criticite > input[type="radio"]::before {
- position: absolute;
- content: '';
- top: 0;
- left: 25%;
- width: 50px;
- height: 50px;
-}
-
.bar-bulle {
position: relative;
}
diff --git a/public/js/app.js b/public/js/app.js
index 6d9ccf87a..bf73b370d 100755
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -15,48 +15,8 @@ for (let iTables = 0; iTables < tables.length; iTables++) {
thead.addEventListener("click", sortTableFunction(table));
}
}
-let isZipForNDE = false
-let hasCriticiteForNDE = false
-let isNDEBail2023 = false;
-let isNDEMissingInfo = false;
-let isNDEDPEBefore2023 = false;
-let hasDPE = false;
-let totalNDEConso = -1;
-let superficieNDE = -1;
-localStorage.clear();
-forms.forEach((form) => {
- form?.querySelectorAll('.toggle-criticite input[type="radio"]')?.forEach((criticite) => {
- criticite.addEventListener('change', (event) => {
- event.currentTarget.parentElement.parentElement.parentElement.querySelector('.fr-toggle__input').checked = true;
- // parent.querySelector('[type="checkbox"]').checked = !parent.querySelector('[type="checkbox"]').checked;
- })
- })
- form?.querySelectorAll('.fr-toggle')?.forEach((t) => {
- t.addEventListener('change', (event) => {
- if (!event.target.checked)
- event.currentTarget.nextElementSibling.querySelectorAll('.fr-collapse input[type="radio"]').forEach((radio) => {
- radio.checked = false
- radio.required = false;
- })
- })
- })
- form?.querySelectorAll('.fr-hover-critere')?.forEach(fhc => {
- fhc.addEventListeners('click touchdown', (event) => {
- if (fhc.parentElement.parentElement.getAttribute('aria-expanded') === "true") {
- let target = form?.querySelector('#' + fhc.parentElement.parentElement.getAttribute('aria-controls'))
- target.classList.remove('fr-fieldset--error')
- target.querySelectorAll('input').forEach(i => {
- i.required = false;
- i.checked = false;
- })
- target.querySelectorAll('.fr-radio-rich img').forEach(img => {
- img.src = img.getAttribute('data-fr-unchecked-icon');
- })
- }
- // if(event.target.parentElement.parentElement.querySelector('[type="checkbox"]'))
- })
- })
+forms.forEach((form) => {
form?.querySelectorAll('.fr-accordion__title')?.forEach((situation) => {
situation.addEventListeners("click touchdown", (event) => {
event.target.parentElement.parentElement.querySelectorAll('[type="radio"],[type="checkbox"]').forEach((ipt) => {
@@ -65,733 +25,7 @@ forms.forEach((form) => {
})
})
})
- form?.querySelectorAll('input[name="signalement[isAllocataire]"]')?.forEach((input) => {
- input.addEventListener('change', (event) => {
- if (event.target.value === 'CAF' || event.target.value === 'MSA') {
- form.querySelector('#signalement-date-naissance-bloc')?.classList.remove('fr-hidden')
- let isOccupant = false
- document.querySelectorAll('input[name="signalement[isNotOccupant]"]').forEach((element) => {
- if (element.value == '0' && element.checked) {
- isOccupant = true
- }
- })
- if (isOccupant) {
- form.querySelector('#signalement-date-naissance-bloc-necessary')?.classList.remove('fr-hidden')
- } else {
- form.querySelector('#signalement-date-naissance-bloc-necessary')?.classList.add('fr-hidden')
- }
- } else {
- form.querySelector('#signalement-date-naissance-bloc')?.classList.add('fr-hidden')
- }
- })
- })
- form?.querySelectorAll('#signalement_cpOccupant')?.forEach((element) => {
- element.addEventListener('change', (event) => {
- let cpOccupant = form.querySelector('#signalement_cpOccupant').value;
- let zipOccupant = cpOccupant.substr(0, 2)
- // Only a few code postal available in territory 69
- if (zipOccupant == '69') {
- 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 {
- form.querySelector('#fr-error-text-code-postal')?.classList?.add('fr-hidden');
- }
- }
-
- // Zip codes available for Non Conformité Energétique
- isZipForNDE = (zipOccupant == '63' || zipOccupant == '89');
-
- refetchAddress(form)
- })
- })
- form?.querySelectorAll('#signalement_villeOccupant')?.forEach((element) => {
- element.addEventListener('change', (event) => {
- refetchAddress(form)
- })
- })
- form?.querySelectorAll('#form-nde input')?.forEach((element) => {
- element.addEventListener('change', (event) => {
- let isEntreeSelected = false;
- let isDPESelected = false;
- let isDateBailSelected = false;
-
- let isEntree2023 = false;
- let isEntreeBefore2023 = false;
- hasDPE = false;
- let isDateDPE2023 = false;
- let isDateDPEBefore2023 = false;
- isNDEMissingInfo = false;
-
- form.querySelectorAll('#form-nde input[name="signalement[dateEntree]"]')?.forEach((element) => {
- if (element.checked) {
- isEntreeSelected = true;
- isEntree2023 = (element.value === '2023-01-02')
- isNDEBail2023 = isEntree2023
- isEntreeBefore2023 = (element.value === '1970-01-01')
- }
- })
- if (isEntreeSelected) {
- if (isEntreeBefore2023) {
- form.querySelectorAll('#form-nde input[name="signalement[dateBail]"]')?.forEach((element) => {
- if (element.checked) {
- isDateBailSelected = true;
- isNDEBail2023 = (element.value === '2023-01-02');
- isNDEMissingInfo = (element.value === 'Je ne sais pas');
- }
- })
- }
- if (isNDEBail2023) {
- form.querySelectorAll('#form-nde input[name="signalement[hasDPE]"]')?.forEach((element) => {
- if (element.checked) {
- isDPESelected = true;
- hasDPE = (element.value === '1');
- isNDEMissingInfo = (element.value === '');
- }
- })
- }
- if (hasDPE) {
- form.querySelectorAll('#form-nde input[name="signalement[dateDPE]"]')?.forEach((element) => {
- if (element.checked) {
- isDateDPE2023 = (element.value === '2023-01-02')
- isDateDPEBefore2023 = (element.value === '1970-01-01')
- }
- })
- }
- }
-
- // Reinit display
- form.querySelector('#form-nde .display-if-entree-2023')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-entree-before-2023')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-has-dpe')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-dpe-2023')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-dpe-before-2023')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-conso-complete')?.classList.add('fr-hidden');
-
- form.querySelector('#form-nde .display-if-missing-info')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-bail-before-2023')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-not-nde')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-nde')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.add('fr-hidden');
-
- // Logical display
- if (isEntree2023) {
- form.querySelector('#form-nde .display-if-entree-2023')?.classList.remove('fr-hidden');
-
- } else if (isEntreeBefore2023) {
- form.querySelector('#form-nde .display-if-entree-before-2023')?.classList.remove('fr-hidden');
-
- if (isNDEBail2023) {
- form.querySelector('#form-nde .display-if-entree-2023')?.classList.remove('fr-hidden');
- } else if (isNDEMissingInfo) {
- form.querySelector('#form-nde .display-if-missing-info')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.remove('fr-hidden');
- return;
- } else if (isDateBailSelected) {
- form.querySelector('#form-nde .display-if-bail-before-2023')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.remove('fr-hidden');
- return;
- }
- }
-
- if (hasDPE) {
- form.querySelector('#form-nde .display-if-has-dpe')?.classList.remove('fr-hidden');
- if (isDateDPE2023) {
- form.querySelector('#form-nde .display-if-dpe-2023')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde button.calculate-conso')?.click();
-
- } else if (isDateDPEBefore2023) {
- form.querySelector('#form-nde .display-if-dpe-before-2023')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde button.calculate-conso')?.click();
- }
- } else if (isNDEMissingInfo) {
- form.querySelector('#form-nde .display-if-missing-info')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.remove('fr-hidden');
- return;
- } else if (isDPESelected) {
- form.querySelector('#form-nde .display-if-nde')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.remove('fr-hidden');
- return;
- }
- })
- })
- form?.querySelectorAll('#form-nde button.calculate-conso')?.forEach((element) => {
- element.addEventListener('click', (event) => {
- form.querySelector('#form-nde .display-if-conso-complete')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .fr-error-consoSizeYear')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .fr-error-consoSizePlusYear')?.classList.add('fr-hidden');
-
- let isDateDPE2023 = false;
- let isDateDPEBefore2023 = false;
- form.querySelectorAll('#form-nde input[name="signalement[dateDPE]"]')?.forEach((element) => {
- if (element.checked) {
- isDateDPE2023 = (element.value === '2023-01-02')
- isDateDPEBefore2023 = (element.value === '1970-01-01')
- }
- })
-
- let consoSizeYear = -1;
- isNDEDPEBefore2023 = false;
- totalNDEConso = -1;
- if (isNDEBail2023) {
- if (isDateDPE2023) {
- let consoSizeYearTxt = form.querySelector('#form-nde input[name="signalement[consoSizeYear]"]')?.value;
- if (consoSizeYearTxt.length > 0) {
- if (isNaN(consoSizeYear)) {
- form.querySelector('#form-nde .fr-error-consoSizeYear')?.classList.remove('fr-hidden');
- } else {
- consoSizeYear = consoSizeYearTxt;
- form.querySelector('#form-nde .display-if-conso-complete span').textContent = consoSizeYear;
- form.querySelector('#form-nde .display-if-conso-complete')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.remove('fr-hidden');
- }
- } else {
- form.querySelector('#form-nde .display-if-conso-complete')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.add('fr-hidden');
- }
- } else if (isDateDPEBefore2023) {
- isNDEDPEBefore2023 = true;
- superficieNDE = form.querySelector('#form-nde input[name="signalement[consoSize]"]')?.value;
- let consoYear = form.querySelector('#form-nde input[name="signalement[consoYear]"]')?.value;
- if (superficieNDE.length > 0 && consoYear.length > 0) {
- if (isNaN(superficieNDE) || isNaN(consoYear)) {
- form.querySelector('#form-nde .fr-error-consoSizePlusYear')?.classList.remove('fr-hidden');
- } else {
- consoSizeYear = Math.round(consoYear / superficieNDE, 2);
- form.querySelector('#form-nde .display-if-conso-complete span').textContent = consoSizeYear;
- form.querySelector('#form-nde .display-if-conso-complete')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.remove('fr-hidden');
- }
- } else {
- form.querySelector('#form-nde .display-if-conso-complete')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-finished')?.classList.add('fr-hidden');
- }
- }
-
- if (consoSizeYear > -1) {
- totalNDEConso = consoSizeYear;
- if (consoSizeYear > 450) {
- form.querySelector('#form-nde .display-if-nde')?.classList.remove('fr-hidden');
- form.querySelector('#form-nde .display-if-not-nde')?.classList.add('fr-hidden');
- } else {
- form.querySelector('#form-nde .display-if-nde')?.classList.add('fr-hidden');
- form.querySelector('#form-nde .display-if-not-nde')?.classList.remove('fr-hidden');
- }
- }
- }
- })
- })
- form?.querySelectorAll('[data-fr-toggle-show],[data-fr-toggle-hide]')?.forEach((toggle) => {
- toggle.addEventListener('change', (event) => {
- let toShow = event.target.getAttribute('data-fr-toggle-show'),
- toHide = event.target.getAttribute('data-fr-toggle-hide'),
- toUnrequire = event.target.getAttribute('data-fr-toggle-unrequire'),
- toRequire = event.target.getAttribute('data-fr-toggle-require')
- toShow && toShow.split('|').map(targetId => {
- let target;
- if (targetId === "signalement-consentement-tiers-bloc") {
- target = document?.querySelector('#signalement-consentement-tiers-bloc');
- target.querySelector('[type="checkbox"]').required = true;
- } else {
- target = form?.querySelector('#' + targetId);
- target.querySelectorAll('input:not([type="checkbox"]),textarea,select').forEach(ipt => {
- if (ipt.name !== "signalement[numAllocataire]") {
- ipt.required = true;
- if (ipt.labels)
- ipt.labels[0].classList.add('required')
- }
- })
- }
- if (target.id === "signalement-methode-contact") {
- target.querySelector('fieldset').setAttribute('aria-required', true)
- }
- target.classList.remove('fr-hidden')
- })
- toHide && toHide.split('|').map(targetId => {
- let target;
- if (targetId === "signalement-consentement-tiers-bloc") {
- target = document.querySelector('#signalement-consentement-tiers-bloc');
- target.querySelector('[type="checkbox"]').required = false
- } else {
- target = form?.querySelector('#' + targetId);
- target?.querySelectorAll('input:not([type="checkbox"]),textarea,select')?.forEach(ipt => {
- ipt.required = false;
- })
- }
- if (target.id === "signalement-methode-contact") {
- target?.querySelector('fieldset[aria-required="true"]')?.removeAttribute('aria-required')
- target?.querySelectorAll('[type="checkbox"]')?.forEach(chk => {
- chk.checked = false;
- })
- }
- target.classList.add('fr-hidden')
- })
- toUnrequire && toUnrequire.split('|').map(targetId => {
- let target = form?.querySelector('#' + targetId);
- if (!target)
- target = document?.querySelector('#' + targetId);
- target.required = false;
- target?.parentElement?.classList?.remove('fr-input-group--error')
- target?.parentElement?.querySelector('.fr-error-text')?.classList.add('fr-hidden')
- target?.classList?.remove('fr-input--error')
- target.labels[0].classList.remove('required')
- })
- toRequire && toRequire.split('|').map(targetId => {
- let target = form?.querySelector('#' + targetId);
- if (!target)
- target = document?.querySelector('#' + targetId);
- target.required = true;
- target?.labels[0]?.classList.add('required')
- })
- })
- })
- form?.querySelectorAll('input[type="file"]')?.forEach((file) => {
- file.addEventListener('change', (event) => {
- if (event.target.files.length > 0) {
- let resTextEl = event.target.parentElement.nextElementSibling;
- let fileData = new FormData();
- let deleter = event.target.parentElement.parentElement.querySelector('.signalement-uploadedfile-delete'),
- /*src = URL.createObjectURL(event.target.files[0]),*/
- preview = event.target?.parentElement?.querySelector('img'),
- fileIsOk = false, file = event.target.files[0];
- let id = event.target.id;
- let progress = document.querySelector("#progress_" + id);
- let totalProgress = document.querySelector('#form_global_file_progress');
- if (preview) {
- if (event.target.files[0].type === 'image/heic' || event.target.files[0].type === 'image/heif') {
- event.target.value = "";
- resTextEl.innerHTML = "Les fichiers de format HEIC/HEIF ne sont pas pris en charge, merci de convertir votre image en JPEG ou en PNG avant de l'envoyer.";
- resTextEl.classList.remove('fr-hidden')
- } else if (event.target.files[0].size > 10 * 1024 * 1024) {
- event.target.value = "";
- resTextEl.innerHTML = "L'image dépasse 10MB";
- resTextEl.classList.remove('fr-hidden')
- } else {
- preview.src = URL.createObjectURL(file);
- ['fr-icon-camera-fill', 'fr-py-7v', 'fr-icon-refresh-line', 'fr-disabled'].map(v => event.target.parentElement.classList.toggle(v));
- fileIsOk = true;
- }
- } else if (event.target.parentElement.classList.contains('fr-icon-attachment-fill')) {
- if (event.target.files[0].type === 'image/heic' || event.target.files[0].type === 'image/heif') {
- event.target.value = "";
- resTextEl.innerHTML = "Les fichiers de format HEIC/HEIF ne sont pas pris en charge, merci de convertir votre image en JPEG ou en PNG avant de l'envoyer.";
- resTextEl.classList.remove('fr-hidden')
- } else if (event.target.files[0].size > 10 * 1024 * 1024) {
- event.target.value = "";
- resTextEl.innerHTML = "Le document dépasse 10MB";
- resTextEl.classList.remove('fr-hidden')
- } else {
- resTextEl.classList.add('fr-hidden')
- fileIsOk = true;
- ['fr-icon-attachment-fill', 'fr-icon-refresh-line', 'fr-disabled'].map(v => event.target.parentElement.classList.toggle(v));
- }
- }
- if (fileIsOk) {
- // [preview, deleter].forEach(el => el?.classList?.remove('fr-hidden'))
- deleter.addEventListeners('click touchdown', (e) => {
- e.preventDefault();
- if (preview) {
- preview.src = '#';
- event.target.parentElement.classList.add('fr-icon-camera-fill')
- } else if (event.target.parentElement.classList.contains('fr-icon-checkbox-circle-fill')) {
- ['fr-icon-attachment-fill', 'fr-icon-checkbox-circle-fill'].map(v => event.target.parentElement.classList.toggle(v));
- } else {
- event.target.parentElement.classList.add('fr-icon-attachment-fill');
- }
- event.target.value = '';
- fileData.delete(event.target.name);
- delete uploadedFiles[event.target.id];
- [preview, deleter].forEach(el => el?.classList.add('fr-hidden'));
- event.target.parentElement.classList.remove('fr-disabled')
- resTextEl.innerText = '';
- })
- fileData.append(event.target.name, file)
- let request = new XMLHttpRequest();
- let finish_submit_btn = document.querySelector('#form_finish_submit');
- request.open('POST', event.target.getAttribute('data-handle-url'));
- request.upload.addEventListener('progress', function (e) {
- console.log('progress');
- console.log(e);
- totalProgress.classList.remove('fr-hidden')
- finish_submit_btn.disabled = true;
- finish_submit_btn.innerHTML = 'Téléversement en cours, veuillez patienter....';
- let activeProgresses = document.querySelectorAll('progress:not(.fr-hidden,.final-progress)');
- let percent_completed = (e.loaded / e.total) * 100;
- let total_percent_completed = 0;
- activeProgresses.forEach(acp => {
- total_percent_completed += acp.value;
- })
- totalProgress.value = total_percent_completed / activeProgresses.length;
- progress.value = percent_completed;
- });
- request.addEventListener('load', function (e) {
- console.log('load');
- console.log(e);
- event.target.parentElement.classList.remove('fr-icon-refresh-line');
- [preview, deleter].forEach(el => el?.classList?.remove('fr-hidden'));
- progress.value = 0;
- let jsonRes = JSON.parse(request.response)
- if (request.status !== 200) {
- progress.value = 0;
- deleter.click();
- resTextEl.innerText = jsonRes.error;
- resTextEl.classList.remove('fr-hidden');
- resTextEl.classList.add('fr-text-label--red-marianne');
- } else {
- resTextEl.innerText = jsonRes.titre
- resTextEl.classList.remove('fr-hidden');
- resTextEl.classList.add('fr-text-label--green-emeraude');
- if (!preview)
- ['fr-icon-checkbox-circle-fill'].map(v => event.target.parentElement.classList.toggle(v));
- uploadedFiles[event.target.id] = request.response;
- }
- progress.classList.add('fr-hidden');
- event.target.value = '';
- if (document.querySelectorAll('progress:not(.fr-hidden,.final-progress)').length < 1) {
- totalProgress.classList.add('fr-hidden')
- finish_submit_btn.innerHTML = 'Confirmer';
- finish_submit_btn.disabled = false;
- }
- });
- progress.classList.remove('fr-hidden')
- request.send(fileData);
- event.target.parentElement.classList.add('fr-disabled')
- }
- }
- })
- })
- form?.querySelectorAll('[data-fr-adresse-autocomplete]').forEach((autocomplete) => {
- autocomplete.addEventListener('keyup', () => {
- searchAddress(form, autocomplete)
- });
- })
- form.addEventListener('submit', (event) => {
- event.preventDefault();
- if (!form.checkValidity() || !checkFirstStep(form) || !checkFieldset(form)) {
- event.stopPropagation();
- if (form.id === "signalement-step-2") {
- form.querySelector('[role="alert"]').classList.remove('fr-hidden')
- form?.querySelectorAll('.fr-fieldset__content.fr-collapse.fr-collapse--expanded').forEach(exp => {
- exp.querySelector('[type="radio"]:first-of-type').required = true;
- if (exp.querySelector('input:invalid')) {
- exp.classList.add('fr-fieldset--error')
- exp.querySelector('.fr-error-text').classList.remove('fr-hidden')
- }
- })
- invalid = form?.querySelector('*:invalid:first-of-type')?.parentElement;
- if (!invalid)
- invalid = document.querySelector("div[role='alert']")
- form.addEventListener('change', () => {
- form?.querySelectorAll('.fr-fieldset__content.fr-collapse.fr-collapse--expanded').forEach(exp => {
- if (null === exp.querySelector('input:invalid')) {
- exp.classList.remove('fr-fieldset--error')
- exp.querySelector('.fr-error-text').classList.add('fr-hidden')
- }
- })
- if (checkFirstStep(form)) {
- form.querySelector('[role="alert"]').classList.add('fr-hidden')
- }
- })
- } else {
- form.querySelectorAll('input,textarea,select,fieldset[aria-required="true"]').forEach((field) => {
- if (field.tagName === "FIELDSET") {
- if (!checkFieldset(form)) {
- field.addEventListener('change', () => {
- checkFieldset(form);
- })
- invalid = field.parentElement;
- }
- } else if (!field.checkValidity()) {
- let parent = field.parentElement;
- if (field.type === 'radio')
- parent = field.parentElement.parentElement.parentElement;
- [field.classList, parent.classList].forEach((f) => {
- f.add(f[0] + '--error');
- })
- parent?.querySelector('.fr-error-text')?.classList.remove('fr-hidden');
- field.addEventListener('input', () => {
- if (field.checkValidity()) {
- [field.classList, parent.classList].forEach((f) => {
- f.remove(f[0] + '--error');
- })
- parent.querySelector('.fr-error-text')?.classList.add('fr-hidden');
- }
- })
- invalid = form?.querySelector('*:invalid:first-of-type')?.parentElement;
- }
-
- })
-
- }
- if (invalid) {
- const y = invalid.getBoundingClientRect().top + window.scrollY;
- window.scroll({
- top: y,
- behavior: 'smooth'
- });
- }
- } else {
- form.querySelectorAll('input,textarea,select').forEach((field) => {
- let parent = field.parentElement;
- if (field.type === 'radio')
- parent = field.parentElement.parentElement.parentElement;
- [field.classList, parent.classList].forEach((f) => {
- f.remove(f[0] + '--error');
- })
- parent.querySelector('.fr-error-text')?.classList.add('fr-hidden');
- })
- if (form.name !== 'signalement') {
- Object.keys(uploadedFiles).map((f, index) => {
- let fi = JSON.parse(uploadedFiles[f]);
- form.insertAdjacentHTML('beforeend', ` `);
- });
- form.submit();
- }
- else {
- let currentTabBtn = document.querySelector('.fr-tabs__list>li>button[aria-selected="true"]'),
- nextTabBtn = currentTabBtn.parentElement?.nextElementSibling?.querySelector('button');
- if (form.id === "signalement-step-1" && form.querySelector('.checkterr')) {
- let inseeParam = '';
- if (form.querySelector('#signalement-insee-occupant').value != undefined && form.querySelector('#signalement-insee-occupant').value != '') {
- inseeParam = '&insee='+form.querySelector('#signalement-insee-occupant').value;
- }
- fetch('checkterritory?cp='+form.querySelector('#signalement_cpOccupant').value+inseeParam).then(r=> r.json()).then(r=> {
- if(r.success)
- {
- nextTabBtn.disabled = false;
- setTimeout(() => {nextTabBtn.click()}, 50)
- } else {
- document.getElementById('fr-modal-closed-territory-content').innerHTML = r.message;
- dsfr(document.querySelector('#fr-modal-closed-territory')).modal.disclose();
- }
- })
- } else {
- if (form.id === "signalement-step-3") {
- if (isZipForNDE && hasCriticiteForNDE) {
- nextTabBtn = document.querySelector('#signalement-step-3b-btn');
- nextTabBtn.classList.remove('fr-hidden');
- document.querySelector('#signalement-step-4-btn > span').textContent = '5';
- document.querySelector('#signalement-step-last-btn > span').textContent = '6';
- } else {
- nextTabBtn = document.querySelector('#signalement-step-3b-btn');
- nextTabBtn.classList.add('fr-hidden');
- nextTabBtn = document.querySelector('#signalement-step-4-btn');
- document.querySelector('#signalement-step-4-btn > span').textContent = '4';
- document.querySelectorAll('#signalement-step-last-btn > span')?.forEach(element => {
- element.textContent = '5';
- })
- }
- }
- if (form.id === "signalement-step-3b") {
- if (superficieNDE > -1) {
- document.querySelector('#signalement_superficie').value = superficieNDE;
- }
- }
-
- if (form.id === "signalement-step-4") {
- document.querySelector('#signalement-date-naissance-bloc .fr-error-text').classList.add('fr-hidden')
- let isOccupant = false
- let isAllocataire = false
- document.querySelectorAll('input[name="signalement[isNotOccupant]"]').forEach((element) => {
- if (element.value == '0' && element.checked) {
- isOccupant = true
- }
- })
- document.querySelectorAll('input[name="signalement[isAllocataire]"]').forEach((element) => {
- if ((element.value == 'CAF' || element.value == 'MSA') && element.checked) {
- isAllocataire = true
- }
- })
- if (isOccupant && isAllocataire) {
- if (document.querySelector('#signalement_dateNaissanceOccupant_day').value == ''
- || document.querySelector('#signalement_dateNaissanceOccupant_month').value == ''
- || document.querySelector('#signalement_dateNaissanceOccupant_year').value == '') {
- document.querySelector('#signalement-date-naissance-bloc .fr-error-text').classList.remove('fr-hidden')
- event.stopPropagation();
- return
- }
- }
- }
-
- if (nextTabBtn) {
- if (nextTabBtn.hasAttribute('data-fr-last-step')) {
- let inputHiddenElement = document.querySelector(
- '#signalement-step-last-panel input[type=hidden]'
- );
-
- fetch('/signalement/csrf-token')
- .then(response => response.json())
- .then(obj => {
- inputHiddenElement.value = obj.csrf_token.value;
- });
-
- var nbDocs = 0;
- var nbPhotos = 0;
- document.querySelector('#recap-signalement-situation').innerHTML = '';
- forms.forEach((form) => {
- form.querySelectorAll('[type="file"]').forEach(file => {
- if (file.classList.contains("doc-file")) {
- if (file.parentElement.classList.contains('fr-icon-checkbox-circle-fill')) {
- nbDocs ++;
- }
- }
- if (file.classList.contains("photo-file")) {
- if (file.previousElementSibling != undefined && file.previousElementSibling.src != undefined && file.previousElementSibling.src != '') {
- nbPhotos ++;
- }
- }
- })
-
- form.querySelectorAll('input,textarea,select').forEach((input) => {
- if (document.querySelector('#recap-' + input.id)) {
- document.querySelector('#recap-' + input.id).innerHTML = `${input.value}`;
- } else if (input.classList.contains('signalement-situation') && input.checked)
- document.querySelector('#recap-signalement-situation').innerHTML += '- ' + input.value + ' ';
- });
- let compAddress = Array( 'signalement_etageOccupant', 'signalement_escalierOccupant', 'signalement_numAppartOccupant', 'signalement_adresseAutreOccupant' );
- for (const str of compAddress) {
- if ( document.querySelector('#recap-' + str).innerHTML == '' ) {
- document.querySelector('#recap-container-' + str).style.display = 'none';
- } else {
- document.querySelector('#recap-container-' + str).style.display = 'inline';
- }
- }
- })
-
- document.querySelector('#recap-signalement_documents').innerHTML = nbDocs + ' document(s) transmis';
- document.querySelector('#recap-signalement_photos').innerHTML = nbPhotos + ' photo(s) transmise(s)';
-
- // Reinit display for non-décence
- updateResultNDE();
- }
- nextTabBtn.disabled = false;
- setTimeout(() => {nextTabBtn.click()}, 50)
- } else if (!nextTabBtn) {
- event.target.querySelector('[type="submit"]').disabled = true;
- ['fr-icon-checkbox-circle-fill', 'fr-icon-refresh-fill'].map(v => event.target.querySelector('[type="submit"]').classList.toggle(v));
- event.target.querySelector('[type="submit"]').innerHTML = "En cours d'envoi..."
- let formData = new FormData();
- forms.forEach((form) => {
- let data = serializeArray(form);
- for (let i = 0; i < Object.keys(data).length; i++) {
- let x = Object.keys(data)[i];
- let y = Object.values(data)[i];
- if (x !== 'signalement[photos]' && x !== 'signalement[documents]')
- formData.append(x, y);
- }
- })
- Object.keys(uploadedFiles).map((f, index) => {
- let fi = JSON.parse(uploadedFiles[f]);
- formData.append(`signalement[files][${fi.key}][${fi.titre}]`, fi.file)
- })
- fetch(form.action, {
- method: "POST",
- body: formData
- }).then((r) => {
-
- if (r.ok) {
- r.json().then((res) => {
- if (res.response === "success") {
- document.querySelectorAll('#signalement-tabs,#signalement-success').forEach(el => {
- el.classList.toggle('fr-hidden')
- window.scroll({
- top: 0,
- behavior: 'smooth'
- });
- })
- localStorage.clear();
- } else if (res.response === "success_edited") {
- localStorage.clear();
- window.location.reload();
- } else {
- event.target.querySelector('[type="submit"]').disabled = false;
- event.target.querySelector('[type="submit"]').innerHTML = "Confirmer";
- ['fr-icon-checkbox-circle-fill', 'fr-icon-refresh-fill'].map(v => event.target.querySelector('[type="submit"]').classList.toggle(v));
- let messageAlert = 'Oups... Il semblerait que vous ayez passé trop de temps sur cette étape ! Retournez à l\'étape précédente puis continuez le formulaire pour régler le problème. Si cela ne fonctionne pas, veuillez réessayer plus tard.';
- if(res.response === "formErrors"){
- messageAlert = "Le formulaire contient des erreurs : \n";
- for (const [key, error] of Object.entries(res.errsMsgList)) {
- messageAlert += "- " + error + "\n";
- }
- }
- alert(messageAlert);
- }
- })
- } else {
- r.text().then(r=>{
- console.log(r)
- })
- event.target.querySelector('[type="submit"]').disabled = false;
- event.target.querySelector('[type="submit"]').innerHTML = "Confirmer";
- ['fr-icon-checkbox-circle-fill', 'fr-icon-refresh-fill'].map(v => event.target.querySelector('[type="submit"]').classList.toggle(v));
- alert('Oups... Il semblerait que vous ayez passé trop de temps sur cette étape ! Retournez à l\'étape précédente puis continuez le formulaire pour régler le problème. Si cela ne fonctionne pas, veuillez réessayer plus tard.')
- }
- })
- }
- }
- }
- }
- })
-})
-document?.querySelectorAll('.fr-tabs__panel')?.forEach((tab) => {
- tab.addEventListener("dsfr.conceal", () => {
- if (tab.id === "signalement-step-2-panel") {
- tab.querySelectorAll('[aria-expanded="true"]').forEach(opened => {
- localStorage.setItem(opened.id, 'true')
- })
- }
- const y = tab.getBoundingClientRect().top + window.scrollY;
- window.scroll({
- top: y,
- behavior: 'smooth'
- });
- });
-})
-document?.querySelectorAll('[data-goto-step]')?.forEach(stepper => {
- stepper.addEventListeners('click touchdown', (evt) => {
- evt.preventDefault();
- goToStep(stepper.getAttribute('data-goto-step'))
- })
-})
-document?.querySelectorAll('.toggle-criticite-smiley').forEach(iptSmiley => {
- iptSmiley.addEventListener('change', (evt) => {
- let icon = evt.target.labels[0]?.parentElement?.querySelector('.fr-radio-rich__img img');
- evt.target.parentElement.parentElement.querySelectorAll('.fr-radio-rich__img img').forEach(iptParentImg => {
- iptParentImg.src = iptParentImg.getAttribute('data-fr-unchecked-icon')
- })
- if (evt.target.checked === true)
- icon.src = evt.target.parentElement.querySelector('.fr-radio-rich__img img').getAttribute('data-fr-checked-icon')
-
- // Browse all options to check if one nte is checked
- hasCriticiteForNDE = false;
- document?.querySelectorAll('.toggle-criticite-smiley').forEach(elmtSmiley => {
- if (elmtSmiley.checked && elmtSmiley.dataset.nde !== undefined) {
- hasCriticiteForNDE = true;
- }
- })
- })
})
-document?.querySelector('#signalement-step-2-panel')?.addEventListener('dsfr.disclose', (ev => {
- ev.target.querySelectorAll('[aria-expanded]').forEach(exp => {
- if (localStorage.getItem(exp.id)) { // noinspection CommaExpressionJS
- document.querySelector('#' + exp.id).setAttribute('aria-expanded', "true"), localStorage.removeItem(exp.id)
- }
- })
-}))
-document?.querySelector('#signalement-step-last-panel')?.addEventListener('dsfr.disclose', (ev => {
- updateResultNDE();
-}))
document?.querySelectorAll(".fr-pagination__link").forEach((e => {
let t, r, a, n = document.querySelector(".fr-pagination__link--prev"),
i = document.querySelector(".fr-pagination__link--next"),
@@ -978,116 +212,4 @@ document.querySelector('#modal-dpe-opener')?.addEventListener('click', (event) =
}
})
})
-})
-
-const refetchAddress = (form) => {
- // If the code postal is manually edited, we reinit the insee/geoloc and fetch the first result
- form.querySelector('#signalement-insee-occupant').value = '';
- form.querySelector('#signalement-geoloc-lat-occupant').value = '';
- form.querySelector('#signalement-geoloc-lng-occupant').value = '';
- let addressComplete = form.querySelector('#signalement_adresseOccupant').value
- addressComplete += ' ' + form.querySelector('#signalement_cpOccupant').value
- addressComplete += ' ' + form.querySelector('#signalement_villeOccupant').value
- fetch('https://api-adresse.data.gouv.fr/search/?q=' + addressComplete).then((res) => {
- res.json().then((r) => {
- let feature = r.features[0];
- form.querySelector('#signalement-insee-occupant').value = feature.properties.citycode;
- let zipOccupant = feature.properties.citycode.substr(0, 2)
- if (zipOccupant == '69' || zipOccupant == '29') {
- const METROPOLE_RHONES_AUTHORIZED_INSEE_CODES = [
- 69091, 69096, 69123, 69149, 69199, 69205, 69290, 69259, 69266,
- 69381, 69382, 69383, 69384, 69385, 69386, 69387, 69388, 69389,
- 69003, 69029, 69033, 69034, 69040, 69044, 69046, 69271, 69063,
- 69273, 69068, 69069, 69071, 69072, 69275, 69081, 69276, 69085,
- 69087, 69088, 69089, 69100, 69279, 69142, 69250, 69116, 69117,
- 69127, 69282, 69283, 69284, 69143, 69152, 69153, 69163, 69286,
- 69168, 69191, 69194, 69204, 69207, 69202, 69292, 69293, 69296,
- 69244, 69256, 69260, 69233, 69278
- ];
- 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 FINISTERE_AUTHORIZED_INSEE_CODES = [29232, 29019];
-
- const AUTHORIZED_INSEE_CODES = METROPOLE_RHONES_AUTHORIZED_INSEE_CODES.concat(
- COR_RHONES_AUTHORIZED_INSEE_CODES,
- FINISTERE_AUTHORIZED_INSEE_CODES
- );
-
- if (AUTHORIZED_INSEE_CODES.indexOf(Number(feature.properties.citycode)) == -1) {
- form.querySelector('#fr-error-text-insee')?.classList?.remove('fr-hidden');
- } else {
- form.querySelector('#fr-error-text-insee')?.classList?.add('fr-hidden');
- }
- }
-
- // Zip codes available for Non Conformité Energétique
- isZipForNDE = (zipOccupant == '63' || zipOccupant == '89');
-
- form.querySelector('#signalement-geoloc-lat-occupant').value = feature.geometry.coordinates[1];
- form.querySelector('#signalement-geoloc-lng-occupant').value = feature.geometry.coordinates[0];
- })
- })
-}
-
-const updateResultNDE = () => {
- document.querySelector('#result-nde').classList.add('fr-hidden');
- document.querySelectorAll('#result-nde .display-if-missing-info').forEach(el => {
- el.classList.add('fr-hidden')
- })
- document.querySelectorAll('#result-nde .display-if-dpe-before-2023').forEach(el => {
- el.classList.add('fr-hidden')
- })
- document.querySelectorAll('#result-nde .display-if-conso').forEach(el => {
- el.classList.add('fr-hidden')
- })
- document.querySelectorAll('#result-nde .display-if-not-nde').forEach(el => {
- el.classList.add('fr-hidden')
- })
- document.querySelectorAll('#result-nde .display-if-nde').forEach(el => {
- el.classList.add('fr-hidden')
- })
- document.querySelectorAll('#result-nde .display-if-nde-no-dpe').forEach(el => {
- el.classList.add('fr-hidden')
- })
- // Results for non-décence
- if (isZipForNDE && hasCriticiteForNDE && isNDEBail2023) {
- document.querySelector('#result-nde').classList.remove('fr-hidden');
- if (isNDEMissingInfo) {
- document.querySelectorAll('#result-nde .display-if-missing-info').forEach(el => {
- el.classList.remove('fr-hidden')
- })
- } else if (!hasDPE) {
- document.querySelectorAll('#result-nde .display-if-nde-no-dpe').forEach(el => {
- el.classList.remove('fr-hidden')
- })
-
- } else if (isNDEBail2023 && totalNDEConso > -1) {
- if (isNDEDPEBefore2023) {
- document.querySelectorAll('#result-nde .display-if-dpe-before-2023').forEach(el => {
- el.classList.remove('fr-hidden')
- })
- }
- document.querySelectorAll('#result-nde .display-if-conso').forEach(el => {
- el.classList.remove('fr-hidden')
- })
- document.querySelector('#result-nde .conso-amount').textContent = totalNDEConso;
- if (totalNDEConso > 450) {
- document.querySelectorAll('#result-nde .display-if-nde').forEach(el => {
- el.classList.remove('fr-hidden')
- })
- } else {
- document.querySelectorAll('#result-nde .display-if-not-nde').forEach(el => {
- el.classList.remove('fr-hidden')
- })
- }
- } else {
- document.querySelector('#result-nde').classList.add('fr-hidden');
- }
-
- }
-}
\ No newline at end of file
+})
\ No newline at end of file
diff --git a/public/js/const.js b/public/js/const.js
index 864eb517e..ff7193326 100755
--- a/public/js/const.js
+++ b/public/js/const.js
@@ -112,28 +112,6 @@ const serializeArray = (form) => {
return response
}, {})
};
-const checkFirstStep = (form) => {
- return !(form.id === "signalement-step-2" && null === form.querySelector('[type="radio"]:checked') || form.id === "signalement-step-2" && form.querySelectorAll('[type="checkbox"]:checked').length !== form.querySelectorAll('[type="radio"]:checked').length);
-}
-const checkFieldset = (form) => {
- let field = form.querySelector('fieldset[aria-required="true"]')
- if (field) {
- if (null === field.querySelector('[type="checkbox"]:checked')) {
- field.classList.add('fr-fieldset--error');
- field?.querySelector('.fr-error-text')?.classList.remove('fr-hidden');
- invalid = field.parentElement;
- return false;
- } else {
- field.classList.remove('fr-fieldset--error');
- field?.querySelector('.fr-error-text')?.classList.add('fr-hidden');
- return true;
- }
- } else
- return true;
-}
-const goToStep = (step) => {
- document.querySelector('#signalement-step-' + step + '-btn').click();
-}
const sortTableFunction = (table) => {
return function (ev) {
if (ev.target.tagName.toLowerCase() === 'A') {
diff --git a/public/js/const.min.js b/public/js/const.min.js
index 5b25cf71c..9a04f1b95 100755
--- a/public/js/const.min.js
+++ b/public/js/const.min.js
@@ -82,34 +82,4 @@ searchAddress=(e,t)=>{
),!1
}, 300 );
}
-
- if ("signalement_adresseProprio" === t.id) {
- idFetchTimeout = setTimeout( () => {
- if (t.value.length > 10) {
- t.removeEventListener('keyup', searchAddress)
- fetch('https://api-adresse.data.gouv.fr/search/?q=' + t.value).then((res) => {
- res.json().then((r) => {
- let container = e.querySelector('#signalement-adresse-pro-suggestion')
- container.innerHTML = '';
- for (let feature of r.features) {
- let suggestion = document.createElement('div');
- suggestion.classList.add(
- 'fr-col-12',
- 'fr-p-3v',
- 'fr-text-label--blue-france',
- 'fr-adresse-suggestion'
- );
- suggestion.innerHTML = feature.properties.label;
- suggestion.addEventListener('click', () => {
- e.querySelector('#signalement_adresseProprio').value = feature.properties.label;
- container.innerHTML = '';
- })
- container.appendChild(suggestion)
- }
- })
- })
- return false;
- }
- }, 300 );
- }
};
\ No newline at end of file
diff --git a/src/DataFixtures/Loader/LoadSignalementData.php b/src/DataFixtures/Loader/LoadSignalementData.php
index 305a06aac..51c75104e 100644
--- a/src/DataFixtures/Loader/LoadSignalementData.php
+++ b/src/DataFixtures/Loader/LoadSignalementData.php
@@ -6,6 +6,7 @@
use App\Entity\Enum\DocumentType;
use App\Entity\Enum\MotifCloture;
use App\Entity\Enum\MotifRefus;
+use App\Entity\Enum\OccupantLink;
use App\Entity\Enum\ProfileDeclarant;
use App\Entity\Enum\Qualification;
use App\Entity\Enum\QualificationStatus;
@@ -19,7 +20,6 @@
use App\Factory\Signalement\InformationProcedureFactory;
use App\Factory\Signalement\SituationFoyerFactory;
use App\Factory\Signalement\TypeCompositionLogementFactory;
-use App\Form\SignalementType;
use App\Repository\CritereRepository;
use App\Repository\CriticiteRepository;
use App\Repository\DesordreCategorieRepository;
@@ -126,6 +126,7 @@ private function loadSignalements(ObjectManager $manager, array $row)
)
->setIsUsagerAbandonProcedure(0);
if (isset($row['is_not_occupant'])) {
+ $linkChoices = OccupantLink::getLabelList();
$signalement
->setIsNotOccupant($row['is_not_occupant'])
->setNomDeclarant($faker->lastName())
@@ -133,7 +134,7 @@ private function loadSignalements(ObjectManager $manager, array $row)
->setTelDeclarant($phoneNumber)
->setMailDeclarant($faker->email())
->setStructureDeclarant($faker->company())
- ->setLienDeclarantOccupant(SignalementType::LINK_CHOICES[array_rand(SignalementType::LINK_CHOICES)]);
+ ->setLienDeclarantOccupant($linkChoices[array_rand($linkChoices)]);
} else {
$signalement->setIsNotOccupant(0);
}
@@ -353,6 +354,7 @@ private function loadNewSignalements(ObjectManager $manager, array $row)
);
if (isset($row['is_not_occupant'])) {
+ $linkChoices = OccupantLink::getLabelList();
$signalement
->setIsNotOccupant($row['is_not_occupant'])
->setNomDeclarant($row['nom_declarant'] ?? $faker->lastName())
@@ -360,7 +362,7 @@ private function loadNewSignalements(ObjectManager $manager, array $row)
->setTelDeclarant($row['tel_declarant'] ?? $phoneNumber)
->setMailDeclarant($row['mail_declarant'] ?? $faker->email())
->setStructureDeclarant($faker->company())
- ->setLienDeclarantOccupant(SignalementType::LINK_CHOICES[array_rand(SignalementType::LINK_CHOICES)]);
+ ->setLienDeclarantOccupant($linkChoices[array_rand($linkChoices)]);
} else {
$signalement->setIsNotOccupant(0);
}
diff --git a/src/Form/SignalementType.php b/src/Form/SignalementType.php
deleted file mode 100755
index 552bc75c6..000000000
--- a/src/Form/SignalementType.php
+++ /dev/null
@@ -1,626 +0,0 @@
- 'PROCHE',
- 'Professionnel' => 'PROFESSIONNEL',
- 'Tuteur / Tutrice' => 'TUTEUR',
- 'Voisin / Voisine' => 'VOISIN',
- 'Autre' => 'AUTRE',
- ];
-
- public function buildForm(FormBuilderInterface $builder, array $options): void
- {
- $signalement = $builder->getData();
- if ($signalement) {
- $signalement->setTelOccupant($signalement->getTelOccupantDecoded());
- $signalement->setTelOccupantBis($signalement->getTelOccupantBisDecoded());
- $signalement->setTelProprio($signalement->getTelProprioDecoded());
- $signalement->setTelDeclarant($signalement->getTelDeclarantDecoded());
- }
-
- $builder
- ->add('details', TextareaType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'minlength' => 10,
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Décrivez le ou les problème(s) rencontré(s)',
- 'help' => 'Proposer une rapide description du ou des problème(s) en 10 caractères minimum.',
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- ])
- ->add('isProprioAverti', ChoiceType::class, [
- 'choice_attr' => [
- 'class' => 'fr-radio',
- ],
- 'choices' => [
- 'Oui' => 1,
- 'Non' => 0,
- 'Ne sais pas' => '',
- ],
- 'expanded' => true,
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Avez-vous informé le propriétaire ou gestionnaire de ces nuisances ?',
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- ])
- ->add('nbAdultes', ChoiceType::class, [
- 'attr' => [
- 'class' => 'fr-select',
- ],
- 'choices' => [1, 2, 3, 4, '4+'],
- 'choice_label' => function ($choice, $key, $value) {
- if (1 === $choice) {
- return $value.' Adulte';
- } elseif ('4+' === $choice) {
- return 'Plus de 4 Adultes';
- }
-
- return $value.' Adultes';
- },
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-select-group',
- ], 'label' => "Nombre d'adultes (personnes majeures occupant le logement)",
- 'placeholder' => '--- Selectionnez ---',
- ])
- ->add('nbEnfantsM6', ChoiceType::class, [
- 'attr' => [
- 'class' => 'fr-select',
- ],
- 'choices' => ['0', 1, 2, 3, 4, '4+'],
- 'choice_label' => function ($choice, $key, $value) {
- if (1 === $choice) {
- return $value.' Enfant';
- } elseif ('4+' === $choice) {
- return 'Plus de 4 Enfants';
- }
-
- return $value.' Enfants';
- },
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-select-group',
- ], 'label' => "Nombre d'enfants de moins de 6 ans",
- 'required' => false,
- 'placeholder' => '--- Selectionnez ---',
- ])
- ->add('nbEnfantsP6', ChoiceType::class, [
- 'attr' => [
- 'class' => 'fr-select',
- ],
- 'choices' => ['0', 1, 2, 3, 4, '4+'],
- 'choice_label' => function ($choice, $key, $value) {
- if (1 === $choice) {
- return $value.' Enfant';
- } elseif ('4+' === $choice) {
- return 'Plus de 4 Enfants';
- }
-
- return $value.' Enfants';
- },
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-select-group',
- ], 'label' => "Nombre d'enfants de plus de 6 ans",
- 'required' => false,
- 'placeholder' => '--- Selectionnez ---',
- ])
- ->add('natureLogement', ChoiceType::class, [
- 'attr' => [
- 'class' => 'fr-select',
- ],
- 'choices' => [
- 'Maison' => 'maison',
- 'Appartement' => 'appartement',
- 'Autre' => 'autre',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-select-group',
- ],
- 'label' => 'Quelle est la nature du logement ?',
- 'placeholder' => '--- Selectionnez ---',
- ])
- ->add('superficie', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'pattern' => '^[0-9]*$',
- 'maxlength' => '25',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-form-group fr-col-2',
- ],
- 'label' => 'Quelle est la superficie du logement (en m²) ?',
- 'required' => false,
- ])
- ->add('isAllocataire', ChoiceType::class, [
- 'choices' => [
- 'CAF' => 'CAF',
- 'MSA' => 'MSA',
- 'Non' => 0,
- 'Ne sais pas' => '',
- ],
- 'choice_attr' => function ($choice, $key, $value) {
- $attr['class'] = 'fr-radio';
- if ('Ne sais pas' === $key || 'Non' === $key) {
- $attr['data-fr-toggle-hide'] = 'signalement-num-alloc-bloc';
- } else {
- $attr['data-fr-toggle-show'] = 'signalement-num-alloc-bloc';
- }
-
- return $attr;
- },
- 'expanded' => true,
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Recevez-vous une allocation logement de la CAF ou de la MSA ?',
- 'help' => "Le cas échéant, merci de renseigner votre numéro d'allocataire.",
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- 'required' => false,
- 'placeholder' => false,
- ])
- ->add('numAllocataire', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '25',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-form-group fr-col-2',
- ],
- 'label' => "Numéro d'allocataire",
- 'help' => "Merci de renseigner votre numéro d'allocataire tel qu'il apparait sur vos documents.",
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- 'required' => false,
- ])
- ->add('dateNaissanceOccupant', BirthdayType::class, [
- 'input' => 'datetime_immutable',
- 'attr' => [
- 'class' => 'fr-input',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-form-group fr-col-2',
- ],
- 'placeholder' => [
- 'year' => 'Année',
- 'month' => 'Mois',
- 'day' => 'Jour',
- ],
- 'label' => 'Date de naissance',
- 'help' => 'Merci de préciser la date de naissance de l\'occupant.',
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- 'required' => false,
- ])
- ->add('isLogementSocial', ChoiceType::class, [
- 'choices' => [
- 'Oui' => 1,
- 'Non' => 0,
- 'Ne sais pas' => '',
- ],
- 'expanded' => true,
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Le logement est-il un logement social ?',
- 'help' => 'Cette information nous aide à optimiser le temps de traitement de votre signalement.',
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- ])
- ->add('isPreavisDepart', ChoiceType::class, [
- 'choices' => [
- 'Oui' => 1,
- 'Non' => 0,
- 'Ne sais pas' => '',
- ],
- 'expanded' => true,
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Avez-vous déposé un préavis de départ pour ce logement ?',
- 'help' => 'Cette information nous aide à optimiser le temps de traitement de votre signalement.',
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- ])
- ->add('isRelogement', ChoiceType::class, [
- 'choices' => [
- 'Oui' => 1,
- 'Non' => 0,
- 'Ne sais pas' => '',
- ],
- 'expanded' => true,
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Avez-vous fait une demande de relogement ou de logement social ?',
- 'help' => 'Cette information nous aide à optimiser le temps de traitement de votre signalement.',
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- ])
- ->add('nomOccupant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '50',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "Nom de l'occupant",
- ])
- ->add('prenomOccupant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '50',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "Prénom de l'occupant",
- ])
- ->add('telOccupant', TelType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'pattern' => self::PATTERN_PHONE_NUMBER,
- 'minlength' => '10',
- 'maxlength' => '15',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "N° téléphone de l'occupant",
- 'required' => false,
- ])
- ->add('telOccupantBis', TelType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'pattern' => self::PATTERN_PHONE_NUMBER,
- 'minlength' => '10',
- 'maxlength' => '15',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "N° téléphone secondaire de l'occupant",
- 'required' => false,
- ])
- ->add('mailOccupant', EmailType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '50',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "Courriel de l'occupant",
- 'required' => false,
- ])
- ->add('adresseOccupant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'data-fr-adresse-autocomplete' => 'true',
- 'maxlength' => '100',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Adresse du logement',
- 'help' => "Commencez à entrer votre adresse et cliquez sur l'une des suggestions. Si vous ne trouvez pas votre adresse, entrez-la manuellement.",
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- ])
- ->add('cpOccupant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'pattern' => '[0-9]{5}',
- 'maxlength' => '5',
- 'minlength' => '5',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Code postal du logement',
- ])
- ->add('villeOccupant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '100',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Ville du logement',
- ])
- ->add('etageOccupant', NumberType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'pattern' => '^(-\d{1,3}|\d{1,3})$',
- 'maxlength' => '3',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Etage',
- 'required' => false,
- ])
- ->add('escalierOccupant', TextType::class, [
- 'row_attr' => [
- 'class' => 'fr-input-group',
- ],
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '200',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Escalier',
- 'required' => false,
- ])
- ->add('numAppartOccupant', TextType::class, [
- 'row_attr' => [
- 'class' => 'fr-input-group',
- ],
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '200',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "N° d'appartement",
- 'required' => false,
- ])
- ->add('adresseAutreOccupant', TextType::class, [
- 'row_attr' => [
- 'class' => 'fr-input-group',
- ],
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '200',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Autre (ex: Residence, lieu-dit,...)',
- 'required' => false,
- ])
- ->add('nomProprio', TextType::class, [
- 'row_attr' => [
- 'class' => 'fr-input-group',
- ],
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '200',
- ],
- 'label_attr' => [
- 'class' => 'fr-label required',
- ],
- 'label' => 'Nom ou raison sociale du propriétaire',
- 'required' => true,
- ])
- ->add('adresseProprio', TextType::class, [
- 'row_attr' => [
- 'class' => 'fr-input-group',
- ],
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '200',
- 'data-fr-adresse-autocomplete' => 'true',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Adresse du propriétaire',
- 'help' => "Commencez à entrer votre adresse et cliquez sur l'une des suggestions. Si vous ne trouvez pas votre adresse, entrez-la manuellement.",
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- 'required' => false,
- ])
- ->add('telProprio', TelType::class, [
- 'row_attr' => [
- 'class' => 'fr-input-group fr-mt-2w',
- ],
- 'attr' => [
- 'class' => 'fr-input',
- 'pattern' => self::PATTERN_PHONE_NUMBER,
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'N° de téléphone du propriétaire',
- 'required' => false,
- ])
- ->add('mailProprio', EmailType::class, [
- 'row_attr' => [
- 'class' => 'fr-input-group',
- ],
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '200',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Courriel du propriétaire',
- 'required' => false,
- ])
- ->add('isNotOccupant', ChoiceType::class, [
- 'choice_attr' => function ($choice, $key, $value) {
- $attr['class'] = 'fr-radio';
- 'Oui' === $key ?
- $attr = [
- 'data-fr-toggle-hide' => 'signalement-pas-occupant|signalement-consentement-tiers-bloc',
- 'data-fr-toggle-show' => 'signalement-occupant|signalement-infos-proprio|signalement-consentement-tiers-bloc',
- 'data-fr-toggle-unrequire' => 'signalement_telOccupantBis|signalement-consentement-tiers|signalement_adresseProprio|signalement_telProprio|signalement_mailProprio|signalement_etageOccupant|signalement_escalierOccupant|signalement_numAppartOccupant|signalement_adresseAutreOccupant|signalement_lienDeclarantOccupant_0',
- 'data-fr-toggle-require' => 'signalement_mailOccupant|signalement_telOccupant',
- ]
- :
- $attr = [
- 'data-fr-toggle-show' => 'signalement-consentement-tiers-bloc|signalement-occupant|signalement-pas-occupant|signalement-infos-proprio',
- 'data-fr-toggle-unrequire' => 'signalement_telOccupantBis|signalement_adresseProprio|signalement_telProprio|signalement_mailProprio|signalement_nomProprio|signalement_structureDeclarant|signalement_mailOccupant|signalement_telOccupant|signalement_etageOccupant|signalement_escalierOccupant|signalement_numAppartOccupant|signalement_adresseAutreOccupant',
- ];
-
- return $attr;
- },
- 'choices' => [
- 'Oui' => 0,
- 'Non' => 1,
- ],
- 'expanded' => true,
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "Êtes-vous l'occupant du logement ?",
- 'help' => "Si vous déposez ce signalement pour le compte de quelqu'un d'autre, merci de nous le faire savoir.",
- 'help_attr' => [
- 'class' => 'fr-hint-text',
- ],
- ])
- ->add('nomDeclarant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '50',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Nom déclarant',
- 'required' => false,
- ])
- ->add('prenomDeclarant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '50',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Prénom déclarant',
- 'required' => false,
- ])
- ->add('telDeclarant', TelType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'pattern' => self::PATTERN_PHONE_NUMBER,
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'N° de téléphone déclarant',
- 'required' => false,
- ])
- ->add('mailDeclarant', EmailType::class, [
- 'attr' => [
- 'class' => 'fr-input fr-fi-mail-line fr-input-wrap',
- 'maxlength' => '200',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Courriel déclarant',
- 'required' => false,
- ])
- ->add('lienDeclarantOccupant', ChoiceType::class, [
- 'choices' => self::LINK_CHOICES,
- 'expanded' => true,
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => "Lien avec l'occupant",
- 'required' => false,
- 'placeholder' => false,
- ])
- ->add('structureDeclarant', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- 'maxlength' => '50',
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'row_attr' => [
- 'class' => 'fr-form-group',
- ],
- 'label' => 'Structure déclarant',
- 'required' => false,
- ]);
-
- $builder->get('etageOccupant')
- ->addModelTransformer(new CallbackTransformer(
- function ($currentEtage): ?int {
- return $currentEtage ? EtageParser::parse($currentEtage) : null;
- },
- function ($updtatedEtage): ?string {
- return $updtatedEtage;
- }
- ));
- }
-
- public function configureOptions(OptionsResolver $resolver): void
- {
- $resolver->setDefaults([
- 'data_class' => Signalement::class,
- 'allow_file_upload' => true,
- 'allow_extra_fields' => true,
- 'attr' => [
- 'class' => 'needs-validation',
- 'novalidate' => true,
- ],
- ]);
- }
-}
From 9deaed3f492e1135362d6de9ab509e1c78174a81 Mon Sep 17 00:00:00 2001
From: emilschn
Date: Mon, 11 Mar 2024 17:03:34 +0100
Subject: [PATCH 03/10] refacto OccupantLink #2294
---
src/Controller/Back/SignalementController.php | 14 ----------
src/Entity/Enum/OccupantLink.php | 27 +++++++------------
2 files changed, 10 insertions(+), 31 deletions(-)
diff --git a/src/Controller/Back/SignalementController.php b/src/Controller/Back/SignalementController.php
index a37884c00..b1e758bf1 100755
--- a/src/Controller/Back/SignalementController.php
+++ b/src/Controller/Back/SignalementController.php
@@ -218,20 +218,6 @@ private function isSignalementNDEActif(?SignalementQualification $signalementQua
return false;
}
- #[Route('/{uuid}/editer', name: 'back_signalement_edit', methods: ['GET', 'POST'])]
- public function editSignalement(
- Signalement $signalement,
- ): Response {
- $this->denyAccessUnlessGranted('SIGN_EDIT', $signalement);
- if (Signalement::STATUS_ACTIVE !== $signalement->getStatut()) {
- $this->addFlash('error', "Ce signalement n'est pas éditable.");
-
- return $this->redirectToRoute('back_index');
- }
-
- return $this->redirectToRoute('back_signalement_view', ['uuid' => $signalement->getUuid()]);
- }
-
#[Route('/{uuid}/supprimer', name: 'back_signalement_delete', methods: 'POST')]
public function deleteSignalement(Signalement $signalement, Request $request, ManagerRegistry $doctrine): Response
{
diff --git a/src/Entity/Enum/OccupantLink.php b/src/Entity/Enum/OccupantLink.php
index 2fb85f1ba..b7337673a 100644
--- a/src/Entity/Enum/OccupantLink.php
+++ b/src/Entity/Enum/OccupantLink.php
@@ -2,8 +2,12 @@
namespace App\Entity\Enum;
+use App\Entity\Behaviour\EnumTrait;
+
enum OccupantLink: string
{
+ use EnumTrait;
+
case PROCHE = 'PROCHE';
case VOISIN = 'VOISIN';
case SECOURS = 'SECOURS';
@@ -11,26 +15,15 @@ enum OccupantLink: string
case PRO = 'PRO';
case AUTRE = 'AUTRE';
- public function label(): string
- {
- return self::getLabelList()[$this->name];
- }
-
- /** @see SignalementType::LINK_CHOICES legacy */
public static function getLabelList(): array
{
return [
- 'PROCHE' => 'Proche',
- 'VOISIN' => 'Voisin',
- 'SECOURS' => 'Services de secours',
- 'BAILLEUR' => 'Bailleur',
- 'PRO' => 'Pro',
- 'AUTRE' => 'Autre',
+ self::PROCHE->name => 'Proche',
+ self::VOISIN->name => 'Voisin',
+ self::SECOURS->name => 'Services de secours',
+ self::BAILLEUR->name => 'Bailleur',
+ self::PRO->name => 'Pro',
+ self::AUTRE->name => 'Autre',
];
}
-
- public static function names(): array
- {
- return array_column(self::cases(), 'name');
- }
}
From db86f76318aa7a5396213164ef8a0f04dcdf3603 Mon Sep 17 00:00:00 2001
From: emilschn
Date: Mon, 11 Mar 2024 17:07:42 +0100
Subject: [PATCH 04/10] move FrontNewSignalementController to
FrontSignalementController #2294
---
.../FrontNewSignalementController.php | 225 ------------------
src/Controller/FrontSignalementController.php | 88 +++++++
2 files changed, 88 insertions(+), 225 deletions(-)
delete mode 100755 src/Controller/FrontNewSignalementController.php
diff --git a/src/Controller/FrontNewSignalementController.php b/src/Controller/FrontNewSignalementController.php
deleted file mode 100755
index 391b83eec..000000000
--- a/src/Controller/FrontNewSignalementController.php
+++ /dev/null
@@ -1,225 +0,0 @@
-redirectToRoute('front_signalement');
- }
-
- #[Route('/signalement-draft/{uuid}', name: 'front_nouveau_formulaire_edit', methods: 'GET')]
- public function edit(
- SignalementDraft $signalementDraft
- ): Response {
- if (
- $signalementDraft
- && SignalementDraftStatus::EN_COURS === $signalementDraft->getStatus()
- ) {
- return $this->render('front/nouveau_formulaire.html.twig', [
- 'uuid_signalement' => $signalementDraft->getUuid(),
- ]);
- }
-
- return $this->redirectToRoute('front_signalement');
- }
-
- #[Route('/signalement-draft/envoi', name: 'envoi_nouveau_signalement_draft', methods: 'POST')]
- public function sendSignalementDraft(
- Request $request,
- SignalementDraftRequestSerializer $serializer,
- SignalementDraftManager $signalementDraftManager,
- ValidatorInterface $validator,
- ): Response {
- /** @var SignalementDraftRequest $signalementDraftRequest */
- $signalementDraftRequest = $serializer->deserialize(
- $payload = $request->getContent(),
- SignalementDraftRequest::class,
- 'json'
- );
- $errors = $validator->validate(
- $signalementDraftRequest,
- null,
- ['Default', 'POST_'.strtoupper($signalementDraftRequest->getProfil())]
- );
- if (0 === $errors->count()) {
- return $this->json([
- 'uuid' => $signalementDraftManager->create(
- $signalementDraftRequest,
- json_decode($payload, true)
- ),
- ]);
- }
-
- return $this->json($errors);
- }
-
- #[Route('/signalement-draft/check', name: 'check_signalement_draft_existe', methods: 'POST')]
- public function checkSignalementDraftExists(
- Request $request,
- SignalementDraftRequestSerializer $serializer,
- SignalementDraftManager $signalementDraftManager,
- ValidatorInterface $validator,
- SignalementDraftFactory $signalementDraftFactory,
- SignalementDraftRepository $signalementDraftRepository,
- ): Response {
- /** @var SignalementDraftRequest $signalementDraftRequest */
- $signalementDraftRequest = $serializer->deserialize(
- $payload = $request->getContent(),
- SignalementDraftRequest::class,
- 'json'
- );
- $errors = $validator->validate(
- $signalementDraftRequest,
- null,
- ['Default', 'POST_'.strtoupper($signalementDraftRequest->getProfil())]
- );
- if (0 === $errors->count()) {
- $dataToHash = $signalementDraftFactory->getEmailDeclarant($signalementDraftRequest);
- $dataToHash .= $signalementDraftRequest->getAdresseLogementAdresse();
- $hash = hash('sha256', $dataToHash);
-
- $existingSignalementDraft = $signalementDraftRepository->findOneBy(
- [
- 'checksum' => $hash,
- 'status' => SignalementDraftStatus::EN_COURS,
- ],
- [
- 'id' => 'DESC',
- ]
- );
-
- if (null !== $existingSignalementDraft) {
- return $this->json([
- 'already_exists' => true,
- 'uuid' => $existingSignalementDraft->getUuid(),
- 'created_at' => $existingSignalementDraft->getCreatedAt(),
- 'updated_at' => $existingSignalementDraft->getUpdatedAt(),
- ]);
- }
-
- return $this->json([
- 'already_exists' => false,
- 'uuid' => $signalementDraftManager->create(
- $signalementDraftRequest,
- json_decode($payload, true)
- ),
- ]);
- }
-
- return $this->json($errors);
- }
-
- #[Route('/signalement-draft/{uuid}/envoi', name: 'mise_a_jour_nouveau_signalement_draft', methods: 'PUT')]
- public function updateSignalementDraft(
- Request $request,
- SignalementDraftRequestSerializer $serializer,
- SignalementDraftManager $signalementDraftManager,
- ValidatorInterface $validator,
- SignalementDraft $signalementDraft,
- ): Response {
- /** @var SignalementDraftRequest $signalementDraftRequest */
- $signalementDraftRequest = $serializer->deserialize(
- $payload = $request->getContent(),
- SignalementDraftRequest::class,
- 'json'
- );
- $groupValidation = ['Default', 'POST_'.strtoupper($signalementDraftRequest->getProfil())];
- if ('validation_signalement' === $signalementDraftRequest->getCurrentStep()) {
- $groupValidation[] = 'PUT_'.strtoupper($signalementDraftRequest->getProfil());
- }
- $errors = $validator->validate($signalementDraftRequest, null, $groupValidation);
- if (0 === $errors->count()) {
- $result = $signalementDraftManager->update(
- $signalementDraft,
- $signalementDraftRequest,
- json_decode($payload, true)
- );
-
- return $this->json($result);
- }
-
- return $this->json($errors);
- }
-
- #[Route('/signalement-draft/{uuid}/informations', name: 'informations_signalement_draft', methods: 'GET')]
- public function getSignalementDraft(
- SignalementDraft $signalementDraft,
- ): Response {
- return $this->json([
- 'signalement' => SignalementDraftStatus::EN_COURS === $signalementDraft->getStatus()
- ? $signalementDraft :
- null,
- ]);
- }
-
- #[Route('/signalement-draft/{uuid}/send_mail', name: 'send_mail_continue_from_draft')]
- public function sendMailContinueFromDraft(
- NotificationMailerRegistry $notificationMailerRegistry,
- SignalementDraft $signalementDraft,
- Request $request
- ): Response {
- if (
- $request->isMethod('POST')
- && $signalementDraft
- && SignalementDraftStatus::EN_COURS === $signalementDraft->getStatus()
- ) {
- $success = $notificationMailerRegistry->send(
- new NotificationMail(
- type: NotificationMailerType::TYPE_CONTINUE_FROM_DRAFT,
- to: $signalementDraft->getEmailDeclarant(),
- signalementDraft: $signalementDraft,
- )
- );
- if ($success) {
- return $this->json(['success' => true]);
- }
-
- return $this->json([
- 'success' => false,
- 'label' => 'Erreur',
- 'message' => 'L\'envoi du mail n\'a pas fonctionné, veuillez réessayer ou faire un nouveau signalement.',
- ]);
- }
-
- return $this->json(['response' => 'error'], Response::HTTP_BAD_REQUEST);
- }
-
- #[Route('/signalement-draft/{uuid}/archive', name: 'archive_draft')]
- public function archiveDraft(
- SignalementDraft $signalementDraft,
- Request $request,
- SignalementDraftManager $signalementDraftManager
- ): Response {
- if (
- $request->isMethod('POST')
- && $signalementDraft
- && SignalementDraftStatus::EN_COURS === $signalementDraft->getStatus()
- ) {
- $signalementDraft->setStatus(SignalementDraftStatus::ARCHIVE);
- $signalementDraftManager->save($signalementDraft);
-
- return $this->json(['success' => true]);
- }
-
- return $this->json(['response' => 'error'], Response::HTTP_BAD_REQUEST);
- }
-}
diff --git a/src/Controller/FrontSignalementController.php b/src/Controller/FrontSignalementController.php
index 6c7de22be..c438a910c 100755
--- a/src/Controller/FrontSignalementController.php
+++ b/src/Controller/FrontSignalementController.php
@@ -2,15 +2,20 @@
namespace App\Controller;
+use App\Dto\Request\Signalement\SignalementDraftRequest;
use App\Entity\Enum\DocumentType;
+use App\Entity\Enum\SignalementDraftStatus;
+use App\Entity\SignalementDraft;
use App\Entity\Suivi;
use App\Entity\User;
use App\Factory\SuiviFactory;
+use App\Manager\SignalementDraftManager;
use App\Manager\SuiviManager;
use App\Manager\UserManager;
use App\Repository\CommuneRepository;
use App\Repository\SignalementRepository;
use App\Repository\UserRepository;
+use App\Serializer\SignalementDraftRequestSerializer;
use App\Service\ImageManipulationHandler;
use App\Service\Signalement\PostalCodeHomeChecker;
use App\Service\Signalement\SignalementFileProcessor;
@@ -22,6 +27,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
#[Route('/')]
class FrontSignalementController extends AbstractController
@@ -33,6 +39,88 @@ public function index(
'uuid_signalement' => null,
]);
}
+
+ #[Route('/signalement-draft/{uuid}', name: 'front_nouveau_formulaire_edit', methods: 'GET')]
+ public function edit(
+ SignalementDraft $signalementDraft
+ ): Response {
+ return $this->render('front/nouveau_formulaire.html.twig', [
+ 'uuid_signalement' => $signalementDraft->getUuid(),
+ ]);
+ }
+
+ #[Route('/signalement-draft/envoi', name: 'envoi_nouveau_signalement_draft', methods: 'POST')]
+ public function sendSignalementDraft(
+ Request $request,
+ SignalementDraftRequestSerializer $serializer,
+ SignalementDraftManager $signalementDraftManager,
+ ValidatorInterface $validator,
+ ): Response {
+ /** @var SignalementDraftRequest $signalementDraftRequest */
+ $signalementDraftRequest = $serializer->deserialize(
+ $payload = $request->getContent(),
+ SignalementDraftRequest::class,
+ 'json'
+ );
+ $errors = $validator->validate(
+ $signalementDraftRequest,
+ null,
+ ['Default', 'POST_'.strtoupper($signalementDraftRequest->getProfil())]
+ );
+ if (0 === $errors->count()) {
+ return $this->json([
+ 'uuid' => $signalementDraftManager->create(
+ $signalementDraftRequest,
+ json_decode($payload, true)
+ ),
+ ]);
+ }
+
+ return $this->json($errors);
+ }
+
+ #[Route('/signalement-draft/{uuid}/envoi', name: 'mise_a_jour_nouveau_signalement_draft', methods: 'PUT')]
+ public function updateSignalementDraft(
+ Request $request,
+ SignalementDraftRequestSerializer $serializer,
+ SignalementDraftManager $signalementDraftManager,
+ ValidatorInterface $validator,
+ SignalementDraft $signalementDraft,
+ ): Response {
+ /** @var SignalementDraftRequest $signalementDraftRequest */
+ $signalementDraftRequest = $serializer->deserialize(
+ $payload = $request->getContent(),
+ SignalementDraftRequest::class,
+ 'json'
+ );
+ $groupValidation = ['Default', 'POST_'.strtoupper($signalementDraftRequest->getProfil())];
+ if ('validation_signalement' === $signalementDraftRequest->getCurrentStep()) {
+ $groupValidation[] = 'PUT_'.strtoupper($signalementDraftRequest->getProfil());
+ }
+ $errors = $validator->validate($signalementDraftRequest, null, $groupValidation);
+ if (0 === $errors->count()) {
+ $result = $signalementDraftManager->update(
+ $signalementDraft,
+ $signalementDraftRequest,
+ json_decode($payload, true)
+ );
+
+ return $this->json($result);
+ }
+
+ return $this->json($errors);
+ }
+
+ #[Route('/signalement-draft/{uuid}/informations', name: 'informations_signalement_draft', methods: 'GET')]
+ public function getSignalementDraft(
+ SignalementDraft $signalementDraft,
+ ): Response {
+ return $this->json([
+ 'signalement' => SignalementDraftStatus::EN_COURS === $signalementDraft->getStatus()
+ ? $signalementDraft :
+ null,
+ ]);
+ }
#[Route('/checkterritory', name: 'front_signalement_check_territory', methods: ['GET'])]
public function checkTerritory(
From 7cb435b7431a53d4b08d415645fd20f286c436ee Mon Sep 17 00:00:00 2001
From: emilschn
Date: Mon, 11 Mar 2024 17:10:57 +0100
Subject: [PATCH 05/10] delete useless form #2294
---
src/Form/SituationType.php | 46 --------------------------------------
1 file changed, 46 deletions(-)
delete mode 100755 src/Form/SituationType.php
diff --git a/src/Form/SituationType.php b/src/Form/SituationType.php
deleted file mode 100755
index 9865bd657..000000000
--- a/src/Form/SituationType.php
+++ /dev/null
@@ -1,46 +0,0 @@
-add('label', TextType::class, [
- 'attr' => [
- 'class' => 'fr-input',
- ],
- ])
- ->add('isActive', ChoiceType::class, [
- 'row_attr' => [
- 'class' => 'fr-select-group',
- ], 'attr' => [
- 'class' => 'fr-select',
- ],
- 'choices' => [
- 'Active' => 1,
- 'Desactivée' => 0,
- ],
- 'label_attr' => [
- 'class' => 'fr-label',
- ],
- 'label' => 'Active',
- ]);
- }
-
- public function configureOptions(OptionsResolver $resolver): void
- {
- $resolver->setDefaults([
- 'data_class' => Situation::class,
- 'allow_extra_fields' => true,
- ]);
- }
-}
From 8ae7735cbabf9721d7ccd5bfaa4072542b19bd91 Mon Sep 17 00:00:00 2001
From: emilschn
Date: Mon, 11 Mar 2024 18:07:54 +0100
Subject: [PATCH 06/10] get back pictures restrictions modal #2294
---
public/js/app.js | 115 ++++++++++++++++++
.../_modal_pictures_restrictions.html.twig | 73 +++++++++++
.../_partials/_signalement_upload.html.twig | 1 +
3 files changed, 189 insertions(+)
create mode 100755 templates/_partials/_modal_pictures_restrictions.html.twig
diff --git a/public/js/app.js b/public/js/app.js
index bf73b370d..54123fdfb 100755
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -25,6 +25,121 @@ forms.forEach((form) => {
})
})
})
+ form?.querySelectorAll('input[type="file"]')?.forEach((file) => {
+ file.addEventListener('change', (event) => {
+ if (event.target.files.length > 0) {
+ let resTextEl = event.target.parentElement.nextElementSibling;
+ let fileData = new FormData();
+ let deleter = event.target.parentElement.parentElement.querySelector('.signalement-uploadedfile-delete'),
+ /*src = URL.createObjectURL(event.target.files[0]),*/
+ preview = event.target?.parentElement?.querySelector('img'),
+ fileIsOk = false, file = event.target.files[0];
+ let id = event.target.id;
+ let progress = document.querySelector("#progress_" + id);
+ let totalProgress = document.querySelector('#form_global_file_progress');
+ if (preview) {
+ if (event.target.files[0].type === 'image/heic' || event.target.files[0].type === 'image/heif') {
+ event.target.value = "";
+ resTextEl.innerHTML = "Les fichiers de format HEIC/HEIF ne sont pas pris en charge, merci de convertir votre image en JPEG ou en PNG avant de l'envoyer.";
+ resTextEl.classList.remove('fr-hidden')
+ } else if (event.target.files[0].size > 10 * 1024 * 1024) {
+ event.target.value = "";
+ resTextEl.innerHTML = "L'image dépasse 10MB";
+ resTextEl.classList.remove('fr-hidden')
+ } else {
+ preview.src = URL.createObjectURL(file);
+ ['fr-icon-camera-fill', 'fr-py-7v', 'fr-icon-refresh-line', 'fr-disabled'].map(v => event.target.parentElement.classList.toggle(v));
+ fileIsOk = true;
+ }
+ } else if (event.target.parentElement.classList.contains('fr-icon-attachment-fill')) {
+ if (event.target.files[0].type === 'image/heic' || event.target.files[0].type === 'image/heif') {
+ event.target.value = "";
+ resTextEl.innerHTML = "Les fichiers de format HEIC/HEIF ne sont pas pris en charge, merci de convertir votre image en JPEG ou en PNG avant de l'envoyer.";
+ resTextEl.classList.remove('fr-hidden')
+ } else if (event.target.files[0].size > 10 * 1024 * 1024) {
+ event.target.value = "";
+ resTextEl.innerHTML = "Le document dépasse 10MB";
+ resTextEl.classList.remove('fr-hidden')
+ } else {
+ resTextEl.classList.add('fr-hidden')
+ fileIsOk = true;
+ ['fr-icon-attachment-fill', 'fr-icon-refresh-line', 'fr-disabled'].map(v => event.target.parentElement.classList.toggle(v));
+ }
+ }
+ if (fileIsOk) {
+ // [preview, deleter].forEach(el => el?.classList?.remove('fr-hidden'))
+ deleter.addEventListeners('click touchdown', (e) => {
+ e.preventDefault();
+ if (preview) {
+ preview.src = '#';
+ event.target.parentElement.classList.add('fr-icon-camera-fill')
+ } else if (event.target.parentElement.classList.contains('fr-icon-checkbox-circle-fill')) {
+ ['fr-icon-attachment-fill', 'fr-icon-checkbox-circle-fill'].map(v => event.target.parentElement.classList.toggle(v));
+ } else {
+ event.target.parentElement.classList.add('fr-icon-attachment-fill');
+ }
+ event.target.value = '';
+ fileData.delete(event.target.name);
+ delete uploadedFiles[event.target.id];
+ [preview, deleter].forEach(el => el?.classList.add('fr-hidden'));
+ event.target.parentElement.classList.remove('fr-disabled')
+ resTextEl.innerText = '';
+ })
+ fileData.append(event.target.name, file)
+ let request = new XMLHttpRequest();
+ let finish_submit_btn = document.querySelector('#form_finish_submit');
+ request.open('POST', event.target.getAttribute('data-handle-url'));
+ request.upload.addEventListener('progress', function (e) {
+ console.log('progress');
+ console.log(e);
+ totalProgress.classList.remove('fr-hidden')
+ finish_submit_btn.disabled = true;
+ finish_submit_btn.innerHTML = 'Téléversement en cours, veuillez patienter....';
+ let activeProgresses = document.querySelectorAll('progress:not(.fr-hidden,.final-progress)');
+ let percent_completed = (e.loaded / e.total) * 100;
+ let total_percent_completed = 0;
+ activeProgresses.forEach(acp => {
+ total_percent_completed += acp.value;
+ })
+ totalProgress.value = total_percent_completed / activeProgresses.length;
+ progress.value = percent_completed;
+ });
+ request.addEventListener('load', function (e) {
+ console.log('load');
+ console.log(e);
+ event.target.parentElement.classList.remove('fr-icon-refresh-line');
+ [preview, deleter].forEach(el => el?.classList?.remove('fr-hidden'));
+ progress.value = 0;
+ let jsonRes = JSON.parse(request.response)
+ if (request.status !== 200) {
+ progress.value = 0;
+ deleter.click();
+ resTextEl.innerText = jsonRes.error;
+ resTextEl.classList.remove('fr-hidden');
+ resTextEl.classList.add('fr-text-label--red-marianne');
+ } else {
+ resTextEl.innerText = jsonRes.titre
+ resTextEl.classList.remove('fr-hidden');
+ resTextEl.classList.add('fr-text-label--green-emeraude');
+ if (!preview)
+ ['fr-icon-checkbox-circle-fill'].map(v => event.target.parentElement.classList.toggle(v));
+ uploadedFiles[event.target.id] = request.response;
+ }
+ progress.classList.add('fr-hidden');
+ event.target.value = '';
+ if (document.querySelectorAll('progress:not(.fr-hidden,.final-progress)').length < 1) {
+ totalProgress.classList.add('fr-hidden')
+ finish_submit_btn.innerHTML = 'Confirmer';
+ finish_submit_btn.disabled = false;
+ }
+ });
+ progress.classList.remove('fr-hidden')
+ request.send(fileData);
+ event.target.parentElement.classList.add('fr-disabled')
+ }
+ }
+ })
+ })
})
document?.querySelectorAll(".fr-pagination__link").forEach((e => {
let t, r, a, n = document.querySelector(".fr-pagination__link--prev"),
diff --git a/templates/_partials/_modal_pictures_restrictions.html.twig b/templates/_partials/_modal_pictures_restrictions.html.twig
new file mode 100755
index 000000000..c3a0aeec0
--- /dev/null
+++ b/templates/_partials/_modal_pictures_restrictions.html.twig
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
Règlementation
+ des photos
+
+
+
+
Comment bien prendre vos photos ?
+
Quelques conseils pour bien prendre
+ vos photos
+
+ Evitez de prendre en photo des personnes ou des objets
+ personnels
+
+ Lorsque vous prenez votre photo, assurez-vous que la
+ luminosité soit suffisante.
+ N’hésitez pas à activer le flash si besoin.
+
+ Assurez-vous que votre photo n’est pas floue.
+ Votre photo doit permettre de rendre compte de la
+ situation globale. Évitez donc les photos prises en gros
+ plan ou les photos qui ne permettent pas de bien évaluer
+ la situation.
+
+
+
+
+
+
+
Rappel concernant les interdictions de
+ photographie
+
Sont interdites les photographies
+ des parties communes présentant un élément
+ d'identification
+
+ d'une personne
+ d'une ou plusieurs boîtes aux lettres
+ d'éléments extérieurs
+ de numéros d'appartements
+ de noms de propriétaires ou locataires de logements
+ de plaque d’immatriculation de véhicules
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/_partials/_signalement_upload.html.twig b/templates/_partials/_signalement_upload.html.twig
index 9689a574d..f56fabe38 100755
--- a/templates/_partials/_signalement_upload.html.twig
+++ b/templates/_partials/_signalement_upload.html.twig
@@ -1,3 +1,4 @@
+{% include '_partials/_modal_pictures_restrictions.html.twig' %}
Joindre des photos du/des problème(s)
From 53dafda71777f9863ea7e6d938da734e85ed3308 Mon Sep 17 00:00:00 2001
From: emilschn
Date: Tue, 12 Mar 2024 14:14:45 +0100
Subject: [PATCH 07/10] cs-fix #2294
---
src/Controller/FrontSignalementController.php | 2 +-
src/Entity/Enum/OccupantLink.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Controller/FrontSignalementController.php b/src/Controller/FrontSignalementController.php
index c438a910c..5c99ae8d9 100755
--- a/src/Controller/FrontSignalementController.php
+++ b/src/Controller/FrontSignalementController.php
@@ -39,7 +39,7 @@ public function index(
'uuid_signalement' => null,
]);
}
-
+
#[Route('/signalement-draft/{uuid}', name: 'front_nouveau_formulaire_edit', methods: 'GET')]
public function edit(
SignalementDraft $signalementDraft
diff --git a/src/Entity/Enum/OccupantLink.php b/src/Entity/Enum/OccupantLink.php
index b7337673a..42f3db215 100644
--- a/src/Entity/Enum/OccupantLink.php
+++ b/src/Entity/Enum/OccupantLink.php
@@ -7,7 +7,7 @@
enum OccupantLink: string
{
use EnumTrait;
-
+
case PROCHE = 'PROCHE';
case VOISIN = 'VOISIN';
case SECOURS = 'SECOURS';
From cbf83ac20d08ff1d77537b998903c08bb1762300 Mon Sep 17 00:00:00 2001
From: emilschn
Date: Tue, 12 Mar 2024 14:34:19 +0100
Subject: [PATCH 08/10] fix test #2294
---
src/Controller/FrontSignalementController.php | 113 ++++++++++++++++++
1 file changed, 113 insertions(+)
diff --git a/src/Controller/FrontSignalementController.php b/src/Controller/FrontSignalementController.php
index 5c99ae8d9..38c8cd7ad 100755
--- a/src/Controller/FrontSignalementController.php
+++ b/src/Controller/FrontSignalementController.php
@@ -8,15 +8,20 @@
use App\Entity\SignalementDraft;
use App\Entity\Suivi;
use App\Entity\User;
+use App\Factory\SignalementDraftFactory;
use App\Factory\SuiviFactory;
use App\Manager\SignalementDraftManager;
use App\Manager\SuiviManager;
use App\Manager\UserManager;
use App\Repository\CommuneRepository;
+use App\Repository\SignalementDraftRepository;
use App\Repository\SignalementRepository;
use App\Repository\UserRepository;
use App\Serializer\SignalementDraftRequestSerializer;
use App\Service\ImageManipulationHandler;
+use App\Service\Mailer\NotificationMail;
+use App\Service\Mailer\NotificationMailerRegistry;
+use App\Service\Mailer\NotificationMailerType;
use App\Service\Signalement\PostalCodeHomeChecker;
use App\Service\Signalement\SignalementFileProcessor;
use App\Service\UploadHandlerService;
@@ -79,6 +84,62 @@ public function sendSignalementDraft(
return $this->json($errors);
}
+ #[Route('/signalement-draft/check', name: 'check_signalement_draft_existe', methods: 'POST')]
+ public function checkSignalementDraftExists(
+ Request $request,
+ SignalementDraftRequestSerializer $serializer,
+ SignalementDraftManager $signalementDraftManager,
+ ValidatorInterface $validator,
+ SignalementDraftFactory $signalementDraftFactory,
+ SignalementDraftRepository $signalementDraftRepository,
+ ): Response {
+ /** @var SignalementDraftRequest $signalementDraftRequest */
+ $signalementDraftRequest = $serializer->deserialize(
+ $payload = $request->getContent(),
+ SignalementDraftRequest::class,
+ 'json'
+ );
+ $errors = $validator->validate(
+ $signalementDraftRequest,
+ null,
+ ['Default', 'POST_'.strtoupper($signalementDraftRequest->getProfil())]
+ );
+ if (0 === $errors->count()) {
+ $dataToHash = $signalementDraftFactory->getEmailDeclarant($signalementDraftRequest);
+ $dataToHash .= $signalementDraftRequest->getAdresseLogementAdresse();
+ $hash = hash('sha256', $dataToHash);
+
+ $existingSignalementDraft = $signalementDraftRepository->findOneBy(
+ [
+ 'checksum' => $hash,
+ 'status' => SignalementDraftStatus::EN_COURS,
+ ],
+ [
+ 'id' => 'DESC',
+ ]
+ );
+
+ if (null !== $existingSignalementDraft) {
+ return $this->json([
+ 'already_exists' => true,
+ 'uuid' => $existingSignalementDraft->getUuid(),
+ 'created_at' => $existingSignalementDraft->getCreatedAt(),
+ 'updated_at' => $existingSignalementDraft->getUpdatedAt(),
+ ]);
+ }
+
+ return $this->json([
+ 'already_exists' => false,
+ 'uuid' => $signalementDraftManager->create(
+ $signalementDraftRequest,
+ json_decode($payload, true)
+ ),
+ ]);
+ }
+
+ return $this->json($errors);
+ }
+
#[Route('/signalement-draft/{uuid}/envoi', name: 'mise_a_jour_nouveau_signalement_draft', methods: 'PUT')]
public function updateSignalementDraft(
Request $request,
@@ -122,6 +183,58 @@ public function getSignalementDraft(
]);
}
+ #[Route('/signalement-draft/{uuid}/send_mail', name: 'send_mail_continue_from_draft')]
+ public function sendMailContinueFromDraft(
+ NotificationMailerRegistry $notificationMailerRegistry,
+ SignalementDraft $signalementDraft,
+ Request $request
+ ): Response {
+ if (
+ $request->isMethod('POST')
+ && $signalementDraft
+ && SignalementDraftStatus::EN_COURS === $signalementDraft->getStatus()
+ ) {
+ $success = $notificationMailerRegistry->send(
+ new NotificationMail(
+ type: NotificationMailerType::TYPE_CONTINUE_FROM_DRAFT,
+ to: $signalementDraft->getEmailDeclarant(),
+ signalementDraft: $signalementDraft,
+ )
+ );
+ if ($success) {
+ return $this->json(['success' => true]);
+ }
+
+ return $this->json([
+ 'success' => false,
+ 'label' => 'Erreur',
+ 'message' => 'L\'envoi du mail n\'a pas fonctionné, veuillez réessayer ou faire un nouveau signalement.',
+ ]);
+ }
+
+ return $this->json(['response' => 'error'], Response::HTTP_BAD_REQUEST);
+ }
+
+ #[Route('/signalement-draft/{uuid}/archive', name: 'archive_draft')]
+ public function archiveDraft(
+ SignalementDraft $signalementDraft,
+ Request $request,
+ SignalementDraftManager $signalementDraftManager
+ ): Response {
+ if (
+ $request->isMethod('POST')
+ && $signalementDraft
+ && SignalementDraftStatus::EN_COURS === $signalementDraft->getStatus()
+ ) {
+ $signalementDraft->setStatus(SignalementDraftStatus::ARCHIVE);
+ $signalementDraftManager->save($signalementDraft);
+
+ return $this->json(['success' => true]);
+ }
+
+ return $this->json(['response' => 'error'], Response::HTTP_BAD_REQUEST);
+ }
+
#[Route('/checkterritory', name: 'front_signalement_check_territory', methods: ['GET'])]
public function checkTerritory(
Request $request,
From 881539f1eff905a14371873df1d2ee721ec633d3 Mon Sep 17 00:00:00 2001
From: emilschn
Date: Tue, 12 Mar 2024 15:07:47 +0100
Subject: [PATCH 09/10] add control to check if user is notified #2294
---
src/EventListener/ActivityListener.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/EventListener/ActivityListener.php b/src/EventListener/ActivityListener.php
index 0e8c81a5c..e04c2ba83 100755
--- a/src/EventListener/ActivityListener.php
+++ b/src/EventListener/ActivityListener.php
@@ -221,7 +221,7 @@ private function isUserNotified($user, $entity): bool
// - if entity is Suivi: we check that the partner of the user is different from the partner of the user who created the suivi
return User::STATUS_ACTIVE === $user->getStatut()
&& !$user->isSuperAdmin() && !$user->isTerritoryAdmin()
- && ($entity instanceof Affectation || $user->getPartner() !== $entity->getCreatedBy()->getPartner());
+ && ($entity instanceof Affectation || ($entity->getCreatedBy() && $user->getPartner() !== $entity->getCreatedBy()->getPartner()));
}
public function preRemove(LifecycleEventArgs $args)
From 909f28df90d98152e533bd4183c33f7f1b81dff4 Mon Sep 17 00:00:00 2001
From: emilschn
Date: Tue, 12 Mar 2024 15:50:29 +0100
Subject: [PATCH 10/10] fix upload in suivi usager #2294
---
public/js/app.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/public/js/app.js b/public/js/app.js
index 54123fdfb..9f09dfe2d 100755
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -140,6 +140,53 @@ forms.forEach((form) => {
}
})
})
+ form.addEventListener('submit', (event) => {
+ event.preventDefault();
+ if (!form.checkValidity() || !checkFieldset(form)) {
+ event.stopPropagation();
+ form.querySelectorAll('input,textarea,select,fieldset[aria-required="true"]').forEach((field) => {
+ if (field.tagName === "FIELDSET") {
+ if (!checkFieldset(form)) {
+ field.addEventListener('change', () => {
+ checkFieldset(form);
+ })
+ invalid = field.parentElement;
+ }
+ } else if (!field.checkValidity()) {
+ let parent = field.parentElement;
+ if (field.type === 'radio')
+ parent = field.parentElement.parentElement.parentElement;
+ [field.classList, parent.classList].forEach((f) => {
+ f.add(f[0] + '--error');
+ })
+ parent?.querySelector('.fr-error-text')?.classList.remove('fr-hidden');
+ field.addEventListener('input', () => {
+ if (field.checkValidity()) {
+ [field.classList, parent.classList].forEach((f) => {
+ f.remove(f[0] + '--error');
+ })
+ parent.querySelector('.fr-error-text')?.classList.add('fr-hidden');
+ }
+ })
+ invalid = form?.querySelector('*:invalid:first-of-type')?.parentElement;
+ }
+
+ })
+ if (invalid) {
+ const y = invalid.getBoundingClientRect().top + window.scrollY;
+ window.scroll({
+ top: y,
+ behavior: 'smooth'
+ });
+ }
+ } else {
+ Object.keys(uploadedFiles).map((f, index) => {
+ let fi = JSON.parse(uploadedFiles[f]);
+ form.insertAdjacentHTML('beforeend', ` `);
+ });
+ form.submit();
+ }
+ })
})
document?.querySelectorAll(".fr-pagination__link").forEach((e => {
let t, r, a, n = document.querySelector(".fr-pagination__link--prev"),