Skip to content

Commit

Permalink
Merge pull request #1861 from MTES-MCT/feature/946-categories-refus
Browse files Browse the repository at this point in the history
[BO - Signalement] Ajout d'une liste de motifs de refus d'affectation ou signalement
  • Loading branch information
sfinx13 authored Nov 3, 2023
2 parents 84abfcd + d75fd5d commit b935226
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 76 deletions.
28 changes: 28 additions & 0 deletions migrations/Version20231031132907.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

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

final class Version20231031132907 extends AbstractMigration
{
public function getDescription(): string
{
return 'add field motif_refus to affectation and signalement tables';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE affectation ADD motif_refus VARCHAR(255) DEFAULT NULL');
$this->addSql('ALTER TABLE signalement ADD motif_refus VARCHAR(255) DEFAULT NULL');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE affectation DROP motif_refus');
$this->addSql('ALTER TABLE signalement DROP motif_refus');
}
}
3 changes: 2 additions & 1 deletion src/Controller/Back/AffectationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ public function affectationResponseSignalement(
&& $response = $request->get('signalement-affectation-response')
) {
$status = isset($response['accept']) ? Affectation::STATUS_ACCEPTED : Affectation::STATUS_REFUSED;
$affectation = $this->affectationManager->updateAffectation($affectation, $user, $status);
$motifRefus = (Affectation::STATUS_REFUSED === $status) ? $response['motifRefus'] : null;
$affectation = $this->affectationManager->updateAffectation($affectation, $user, $status, $motifRefus);

$suiviAffectationAccepted = $suiviRepository->findSuiviByDescription(
$signalement,
Expand Down
16 changes: 7 additions & 9 deletions src/Controller/Back/SignalementActionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
namespace App\Controller\Back;

use App\Entity\Affectation;
use App\Entity\Enum\MotifRefus;
use App\Entity\Signalement;
use App\Entity\Suivi;
use App\Entity\Tag;
use App\Entity\User;
use App\Service\Mailer\NotificationMail;
use App\Service\Mailer\NotificationMailerRegistry;
use App\Service\Mailer\NotificationMailerType;
use App\Service\Signalement\QualificationStatusService;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
Expand All @@ -20,7 +20,6 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

#[Route('/bo/signalements')]
class SignalementActionController extends AbstractController
Expand All @@ -30,9 +29,7 @@ public function validationResponseSignalement(
Signalement $signalement,
Request $request,
ManagerRegistry $doctrine,
UrlGeneratorInterface $urlGenerator,
NotificationMailerRegistry $notificationMailerRegistry,
QualificationStatusService $qualificationStatusService
): Response {
$this->denyAccessUnlessGranted('SIGN_VALIDATE', $signalement);
if ($this->isCsrfTokenValid('signalement_validation_response_'.$signalement->getId(), $request->get('_token'))
Expand All @@ -58,6 +55,7 @@ public function validationResponseSignalement(
}
} else {
$statut = Signalement::STATUS_REFUSED;
$signalement->setMotifRefus(MotifRefus::tryFrom($response['motifRefus']));
$description = 'cloturé car non-valide avec le motif suivant :<br>'.$response['suivi'];

$toRecipients = $signalement->getMailUsagers();
Expand All @@ -72,11 +70,11 @@ public function validationResponseSignalement(
);
}
$suivi = new Suivi();
$suivi->setSignalement($signalement);
$suivi->setDescription('Signalement '.$description);
$suivi->setCreatedBy($this->getUser());
$suivi->setIsPublic(true);
$suivi->setType(SUIVI::TYPE_AUTO);
$suivi->setSignalement($signalement)
->setDescription('Signalement '.$description)
->setCreatedBy($this->getUser())
->setIsPublic(true)
->setType(SUIVI::TYPE_AUTO);
$signalement->setStatut($statut);
$doctrine->getManager()->persist($signalement);
$doctrine->getManager()->persist($suivi);
Expand Down
1 change: 1 addition & 0 deletions src/DataFixtures/Files/Affectation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ affectations:
answered_by: "[email protected]"
affected_by: "[email protected]"
motif_cloture: ""
motif_refus: "DOUBLON"
territory: "Isère"
-
signalement: 2023-23
Expand Down
1 change: 1 addition & 0 deletions src/DataFixtures/Files/Signalement.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,7 @@ signalements:
cp_occupant: "13003"
ville_occupant: "Marseille"
statut: 8
motif_refus: "DOUBLON"
code_suivi: '0123456784569'
reference: "2023-21"
geoloc: "{\"lng\":\"43.3117791\", \"lat\":\"5.3755551\"}"
Expand Down
6 changes: 6 additions & 0 deletions src/DataFixtures/Loader/LoadAffectationData.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Entity\Affectation;
use App\Entity\Enum\MotifCloture;
use App\Entity\Enum\MotifRefus;
use App\Repository\PartnerRepository;
use App\Repository\SignalementRepository;
use App\Repository\TerritoryRepository;
Expand Down Expand Up @@ -51,6 +52,11 @@ public function loadAffectation(ObjectManager $manager, array $row): void
->setMotifCloture(MotifCloture::tryFrom($row['motif_cloture']));
}

if (Affectation::STATUS_REFUSED === $row['statut'] && '' !== $row['motif_refus']) {
$affectation
->setMotifRefus(MotifRefus::tryFrom($row['motif_refus']));
}

$manager->persist($affectation);
}

Expand Down
6 changes: 6 additions & 0 deletions src/DataFixtures/Loader/LoadSignalementData.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Entity\Criticite;
use App\Entity\Enum\MotifCloture;
use App\Entity\Enum\MotifRefus;
use App\Entity\Enum\Qualification;
use App\Entity\Enum\QualificationStatus;
use App\Entity\File;
Expand Down Expand Up @@ -136,6 +137,11 @@ private function loadSignalements(ObjectManager $manager, array $row)
->setClosedBy($this->userRepository->findOneBy(['statut' => User::STATUS_ACTIVE]));
}

if (Signalement::STATUS_REFUSED === $row['statut']) {
$signalement
->setMotifRefus(MotifRefus::tryFrom($row['motif_refus']));
}

if (isset($row['tags'])) {
foreach ($row['tags'] as $tag) {
$signalement->addTag($this->tagRepository->findOneBy(['label' => $tag]));
Expand Down
16 changes: 16 additions & 0 deletions src/Entity/Affectation.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Entity;

use App\Entity\Enum\MotifCloture;
use App\Entity\Enum\MotifRefus;
use App\Repository\AffectationRepository;
use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection;
Expand Down Expand Up @@ -47,6 +48,9 @@ class Affectation
#[ORM\ManyToOne(targetEntity: User::class)]
private ?User $affectedBy;

#[ORM\Column(type: 'string', enumType: MotifRefus::class, nullable: true)]
private ?MotifRefus $motifRefus;

#[ORM\Column(type: 'string', enumType: MotifCloture::class, nullable: true)]
private ?MotifCloture $motifCloture;

Expand Down Expand Up @@ -153,6 +157,18 @@ public function setAffectedBy(?User $affectedBy): self
return $this;
}

public function getMotifRefus(): ?MotifRefus
{
return $this->motifRefus;
}

public function setMotifRefus(?MotifRefus $motifRefus): self
{
$this->motifRefus = $motifRefus;

return $this;
}

public function getMotifCloture(): ?MotifCloture
{
return $this->motifCloture;
Expand Down
28 changes: 28 additions & 0 deletions src/Entity/Enum/MotifRefus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Entity\Enum;

enum MotifRefus: string
{
case HORS_PDLHI = 'HORS_PDLHI';
case HORS_ZONE_GEOGRAPHIQUE = 'HORS_ZONE_GEOGRAPHIQUE';
case HORS_COMPETENCE = 'HORS_COMPETENCE';
case DOUBLON = 'DOUBLON';
case AUTRE = 'AUTRE';

public function label(): string
{
return self::getLabelList()[$this->name];
}

public static function getLabelList(): array
{
return [
'HORS_PDLHI' => 'Hors PDLHI',
'HORS_ZONE_GEOGRAPHIQUE' => 'Hors zone géographique',
'HORS_COMPETENCE' => 'Hors compétence',
'DOUBLON' => 'Doublon',
'AUTRE' => 'Autre',
];
}
}
16 changes: 16 additions & 0 deletions src/Entity/Signalement.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Entity;

use App\Entity\Enum\MotifCloture;
use App\Entity\Enum\MotifRefus;
use App\Entity\Enum\ProfileDeclarant;
use App\Entity\Model\InformationComplementaire;
use App\Entity\Model\InformationProcedure;
Expand Down Expand Up @@ -313,6 +314,9 @@ class Signalement
#[ORM\Column(type: 'string', enumType: MotifCloture::class, nullable: true)]
private ?MotifCloture $motifCloture;

#[ORM\Column(type: 'string', enumType: MotifRefus::class, nullable: true)]
private ?MotifRefus $motifRefus;

#[ORM\Column(type: 'datetime_immutable', nullable: true)]
private $closedAt;

Expand Down Expand Up @@ -1526,6 +1530,18 @@ public function setMotifCloture(?MotifCloture $motifCloture): self
return $this;
}

public function getMotifRefus(): ?MotifRefus
{
return $this->motifRefus;
}

public function setMotifRefus(?MotifRefus $motifRefus): self
{
$this->motifRefus = $motifRefus;

return $this;
}

public function getClosedAt(): ?DateTimeImmutable
{
return $this->closedAt;
Expand Down
7 changes: 6 additions & 1 deletion src/Manager/AffectationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Entity\Affectation;
use App\Entity\Enum\MotifCloture;
use App\Entity\Enum\MotifRefus;
use App\Entity\Partner;
use App\Entity\Signalement;
use App\Entity\User;
Expand All @@ -21,13 +22,17 @@ public function __construct(
parent::__construct($this->managerRegistry, $entityName);
}

public function updateAffectation(Affectation $affectation, User $user, string $status): Affectation
public function updateAffectation(Affectation $affectation, User $user, string $status, ?string $motifRefus = null): Affectation
{
$affectation
->setStatut($status)
->setAnsweredBy($user)
->setAnsweredAt(new \DateTimeImmutable());

if (!empty($motifRefus)) {
$affectation->setMotifRefus(MotifRefus::tryFrom($motifRefus));
}

$this->save($affectation);

return $affectation;
Expand Down
81 changes: 49 additions & 32 deletions templates/_partials/_modal_refus_affectation.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,56 @@
<div class="fr-grid-row fr-grid-row--center">
<div class="fr-col-12 fr-col-md-8 fr-col-lg-6">
<div class="fr-modal__body">
<div class="fr-modal__header">
<h1 id="refus-affectation-modal-title" class="fr-modal__title">
<span class="fr-fi-arrow-right-line fr-fi--sm"></span>
Refus signalement #{{ signalement.reference }}
</h1>
<a href="#" class="fr-link--close fr-link" aria-controls="refus-affectation-modal">Fermer</a>
</div>
<div class="fr-modal__content">
<div class="fr-input-group fr-mt-2v fr-text--left">
<label for="refus_affectation_suivi" class="fr-label required">Motif du refus</label>
<p class="fr-hint-text">Veuillez préciser le motif de ce refus <em>(10 caractères
minimum)</em></p>
<textarea class="fr-input fr-input--no-resize editor"
name="signalement-affectation-response[suivi]"
id="refus_affectation_suivi"></textarea>
<p class="fr-error-text fr-hidden">Vous devez indiquer le motif de votre refus.</p>
<form action="{{ path('back_signalement_affectation_response',{signalement:signalement.id,user:app.user.id,affectation:isAffected.id}) }}"
class="tinyCheck fr-mb-3v" id="signalement-affectation-response-deny-form"
name="signalement-affectation-response-form" method="POST">
<div class="fr-modal__header">
<h1 id="refus-affectation-modal-title" class="fr-modal__title">
<span class="fr-fi-arrow-right-line fr-fi--sm"></span>
Refus signalement #{{ signalement.reference }}
</h1>
<a href="#" class="fr-link--close fr-link" aria-controls="refus-affectation-modal">Fermer</a>
</div>
</div>
<div class="fr-modal__footer">
<ul class="fr-btns-group fr-btns-group--right fr-btns-group--icon-left">
<li>
<button class="fr-btn fr-btn--danger fr-w-100"
form="signalement-affectation-response-form" type="submit"
name="signalement-affectation-response[deny]" value="1" disabled
onclick="return confirm('Êtes-vous certain de vouloir refuser ce signalement ?')">
Ce
n'est pas
pour
moi
</button>
</li>
</ul>
</div>
<div class="fr-modal__content fr-text--left">
<div class="fr-select-group">
<label class="fr-label required" for="signalement-affectation-response[motifRefus]">
Veuillez sélectionner le motif de refus
</label>
<p class="fr-error-text fr-hidden">Vous devez sélectionner le motif de votre refus.</p>
<select class="fr-select" id="signalement-affectation-response[motifRefus]" name="signalement-affectation-response[motifRefus]" required>
<option value="" selected disabled hidden>Selectionnez une option</option>
<option value="{{ enum('App\\Entity\\Enum\\MotifRefus').HORS_ZONE_GEOGRAPHIQUE.name }}">{{ enum('App\\Entity\\Enum\\MotifRefus').HORS_ZONE_GEOGRAPHIQUE.label }}</option>
<option value="{{ enum('App\\Entity\\Enum\\MotifRefus').HORS_COMPETENCE.name }}">{{ enum('App\\Entity\\Enum\\MotifRefus').HORS_COMPETENCE.label }}</option>
<option value="{{ enum('App\\Entity\\Enum\\MotifRefus').DOUBLON.name }}">{{ enum('App\\Entity\\Enum\\MotifRefus').DOUBLON.label }}</option>
<option value="{{ enum('App\\Entity\\Enum\\MotifRefus').AUTRE.name }}">{{ enum('App\\Entity\\Enum\\MotifRefus').AUTRE.label }}</option>
</select>
</div>
<div class="fr-input-group fr-mt-2v fr-text--left">
<label for="refus_affectation_suivi" class="fr-label required">Message aux partenaires</label>
<p class="fr-hint-text">Expliquez aux autres partenaires la raison du refus de ce signalement
<em>(10 caractères minimum)</em>
</p>
<textarea class="fr-input fr-input--no-resize editor"
name="signalement-affectation-response[suivi]"
id="refus_affectation_suivi"></textarea>
<p class="fr-error-text fr-hidden">Vous devez saisir un message pour les partenaires.</p>
</div>
</div>
<div class="fr-modal__footer">
<ul class="fr-btns-group fr-btns-group--right fr-btns-group--icon-left">
<li>
<button class="fr-btn fr-btn--danger fr-w-100"
form="signalement-affectation-response-deny-form" type="submit"
name="signalement-affectation-response[deny]" value="1" disabled
onclick="return confirm('Êtes-vous certain de vouloir refuser ce signalement ?')">
Refuser l'affectation
</button>
</li>
</ul>
</div>
<input type="hidden" name="_token"
value="{{ csrf_token('signalement_affectation_response_'~signalement.id) }}">
</form>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit b935226

Please sign in to comment.