Commit 37060a56 authored by Cédric Girardot's avatar Cédric Girardot

Feat: Fix #70 Ajoute l'alerte décès

Change-Id: Ib7f880aecfdecb6a9124f24e73fe428abc7df225
parent 910ab4b1
...@@ -30,7 +30,7 @@ pipeline { ...@@ -30,7 +30,7 @@ pipeline {
sh "composer config cache-dir '${env.WORKSPACE}/.cache/.composer'" sh "composer config cache-dir '${env.WORKSPACE}/.cache/.composer'"
sh 'composer install --no-progress --no-suggest --no-interaction --no-scripts' sh 'composer install --no-progress --no-suggest --no-interaction --no-scripts'
sh 'yarn && yarn run build' sh 'yarn && yarn run build'
sh 'bin/console doctrine:schema:update --force' sh 'bin/console doctrine:migration:migrate --no-interaction'
sh 'bin/console cache:clear' sh 'bin/console cache:clear'
sh 'chown -R www-data: .' sh 'chown -R www-data: .'
} }
......
This diff is collapsed.
...@@ -71,7 +71,6 @@ class SearchController extends BaseController ...@@ -71,7 +71,6 @@ class SearchController extends BaseController
) { ) {
$searchData = new SearchData(); $searchData = new SearchData();
$persons = null; $persons = null;
$sendMailToInstructor = true;
$form = $this->createForm(SearchType::class, $searchData); $form = $this->createForm(SearchType::class, $searchData);
$form->handleRequest($request); $form->handleRequest($request);
...@@ -82,6 +81,7 @@ class SearchController extends BaseController ...@@ -82,6 +81,7 @@ class SearchController extends BaseController
$personRepository = $entityManager->getRepository(Person::class); $personRepository = $entityManager->getRepository(Person::class);
$useSoundex = $this->settingsData->hasSoundexSearch(); $useSoundex = $this->settingsData->hasSoundexSearch();
$person = null; $person = null;
$searchStatus = SearchHelper::SEARCH_STATUS_NOTFIND;
$sendMailToInstructor = true; $sendMailToInstructor = true;
[$searchStatus, $person] = $this->searchPerson($personRepository, $searchData, $useSoundex); [$searchStatus, $person] = $this->searchPerson($personRepository, $searchData, $useSoundex);
...@@ -103,6 +103,9 @@ class SearchController extends BaseController ...@@ -103,6 +103,9 @@ class SearchController extends BaseController
$this->translator->trans('searchResult.responseType.'.$searchStatus) $this->translator->trans('searchResult.responseType.'.$searchStatus)
); );
// Envoie de l'alerte décès si la date de décès ne correspond pas à ce qui se trouve en base
$this->sendDeathAlert($person, $searchData, $mailService);
$searchLog = $this->addSearchLog($searchData, $searchStatus, $person); $searchLog = $this->addSearchLog($searchData, $searchStatus, $person);
if ($sendMailToInstructor) { if ($sendMailToInstructor) {
...@@ -355,19 +358,19 @@ class SearchController extends BaseController ...@@ -355,19 +358,19 @@ class SearchController extends BaseController
$mailSubject = $this->translator->trans( $mailSubject = $this->translator->trans(
'searchResultMail.subject.default', 'searchResultMail.subject.default',
[ [
'%appName%' => $this->settingsData->getAppName(), '%appName%' => $this->settingsData->getAppName(),
'%recipient%' => $searchData->getRecipient(), '%recipient%' => $searchData->getRecipient(),
'%firstName%' => $searchData->getFirstName(), '%firstName%' => $searchData->getFirstName(),
'%name%' => $searchData->getName($this->settingsData), '%name%' => $searchData->getName($this->settingsData),
] ]
); );
} else { } else {
$mailSubject = $this->translator->trans( $mailSubject = $this->translator->trans(
'searchResultMail.subject.norecipient', 'searchResultMail.subject.norecipient',
[ [
'%appName%' => $this->settingsData->getAppName(), '%appName%' => $this->settingsData->getAppName(),
'%firstName%' => $searchData->getFirstName(), '%firstName%' => $searchData->getFirstName(),
'%name%' => $searchData->getName($this->settingsData), '%name%' => $searchData->getName($this->settingsData),
] ]
); );
} }
...@@ -391,9 +394,9 @@ class SearchController extends BaseController ...@@ -391,9 +394,9 @@ class SearchController extends BaseController
case SearchHelper::SEARCH_STATUS_FIND_NOTREC: case SearchHelper::SEARCH_STATUS_FIND_NOTREC:
$person = $personService->getPerson($searchLog->getPerson()); $person = $personService->getPerson($searchLog->getPerson());
$mailParametersBdd = [ $mailParametersBdd = [
'firstNameBdd' => $person->getFirstName(), 'firstNameBdd' => $person->getFirstName(),
'nameBdd' => strtoupper($person->getName($this->settingsData)), 'nameBdd' => strtoupper($person->getName($this->settingsData)),
'birthDateBdd' => $person->getBirthDate(), 'birthDateBdd' => $person->getBirthDate(),
]; ];
$mailParameters = array_merge($mailParameters, $mailParametersBdd); $mailParameters = array_merge($mailParameters, $mailParametersBdd);
$mailTemplate = 'emails/search_find.html.twig'; $mailTemplate = 'emails/search_find.html.twig';
...@@ -573,4 +576,79 @@ class SearchController extends BaseController ...@@ -573,4 +576,79 @@ class SearchController extends BaseController
return [$searchStatus, $person]; return [$searchStatus, $person];
} }
/**
* Envoie le mail d'alerte décès
*
* @param Person $person
* @param SearchData $searchData
* @param MailService $mailService
*
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
private function sendDeathAlertMail(Person $person, SearchData $searchData, MailService $mailService)
{
/** @var User $user */
$user = $this->getUser();
$mailSubject = $this->translator->trans(
'searchDeathAlertMail.subject.default',
[
'%appName%' => $this->settingsData->getAppName(),
]
);
$mailTemplate = 'emails/death_alert.html.twig';
$mailParameters = [
'userName' => $user->getName(),
'userEmail' => $user->getEmail(),
'gender' => $person->getGender(),
'firstName' => $person->getFirstName(),
'useName' => $person->getUseName(),
'civilName' => $person->getCivilName(),
'birthDate' => $person->getBirthDate(),
'deathDate' => $searchData->getDeathDate(),
'deathLocation' => $searchData->getDeathLocation(),
];
$mailRecipients = [];
$mailRecipients[] = $this->settingsData->getDeathAlertMail();
$mailHtml = $this->renderView(
$mailTemplate,
$mailParameters
);
if (!empty($mailRecipients)) {
$mailService->sendHtmlMail($mailRecipients, $mailSubject, $mailHtml);
}
}
/**
* @param Person $person
* @param SearchData $searchData
* @param MailService $mailService
*
* @return bool
* @throws TransportExceptionInterface
* @throws \Twig\Error\LoaderError
* @throws \Twig\Error\RuntimeError
* @throws \Twig\Error\SyntaxError
*/
private function sendDeathAlert(?Person $person, SearchData $searchData, MailService $mailService = null)
{
if ($person && $this->settingsData->hasDeathAlert() && $this->settingsData->getDeathAlertMail() &&
$searchData->getDeathDate() !== $person->getDeathDate()) {
if ($mailService) {
$this->sendDeathAlertMail($person, $searchData, $mailService);
}
return true;
}
return false;
}
} }
...@@ -70,6 +70,17 @@ class SettingsData ...@@ -70,6 +70,17 @@ class SettingsData
*/ */
protected $searchByName = SearchHelper::SEARCH_BY_USE_NAME; protected $searchByName = SearchHelper::SEARCH_BY_USE_NAME;
/**
* @var bool
* @BooleanSetting
*/
protected $deathAlert = false;
/**
* @var string
*/
protected $deathAlertMail;
/** /**
* @var string * @var string
*/ */
...@@ -400,6 +411,45 @@ class SettingsData ...@@ -400,6 +411,45 @@ class SettingsData
return $this; return $this;
} }
/**
* @return bool
*/
public function hasDeathAlert(): bool
{
return $this->deathAlert;
}
/**
* @param bool $deathAlert
*
* @return SettingsData
*/
public function setDeathAlert(bool $deathAlert): SettingsData
{
$this->deathAlert = $deathAlert;
return $this;
}
/**
* @return string
*/
public function getDeathAlertMail(): ?string
{
return $this->deathAlertMail;
}
/**
* @param string $deathAlertMail
*
* @return SettingsData
*/
public function setDeathAlertMail(string $deathAlertMail): SettingsData
{
$this->deathAlertMail = $deathAlertMail;
return $this;
}
/** /**
* @return string * @return string
......
...@@ -59,6 +59,12 @@ abstract class AbstractPersonFixtures extends \Doctrine\Bundle\FixturesBundle\Fi ...@@ -59,6 +59,12 @@ abstract class AbstractPersonFixtures extends \Doctrine\Bundle\FixturesBundle\Fi
$person->setLabel(trim($personData['libelle'])); $person->setLabel(trim($personData['libelle']));
$person->setHelpCode(trim($personData['code'])); $person->setHelpCode(trim($personData['code']));
if (array_key_exists('date_deces', $personData)) {
$person->setDeathDate(
\DateTime::createFromFormat('Y-m-j', trim($personData['date_deces'])) ?: null
);
}
$manager->persist($person); $manager->persist($person);
} }
......
...@@ -2,9 +2,16 @@ ...@@ -2,9 +2,16 @@
namespace App\DataFixtures; namespace App\DataFixtures;
use App\Helper\FixturesHelper;
use App\Helper\SearchHelper; use App\Helper\SearchHelper;
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
class PersonCivilNameFixtures extends AbstractPersonFixtures class PersonCivilNameFixtures extends AbstractPersonFixtures implements FixtureGroupInterface
{ {
protected $nameToUse = SearchHelper::SEARCH_BY_CIVIL_NAME; protected $nameToUse = SearchHelper::SEARCH_BY_CIVIL_NAME;
public static function getGroups(): array
{
return [FixturesHelper::GROUP_CIVIL_NAME];
}
} }
...@@ -2,9 +2,16 @@ ...@@ -2,9 +2,16 @@
namespace App\DataFixtures; namespace App\DataFixtures;
use App\Helper\FixturesHelper;
use App\Helper\SearchHelper; use App\Helper\SearchHelper;
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
class PersonUseNameFixtures extends AbstractPersonFixtures class PersonUseNameFixtures extends AbstractPersonFixtures implements FixtureGroupInterface
{ {
protected $nameToUse = SearchHelper::SEARCH_BY_USE_NAME; protected $nameToUse = SearchHelper::SEARCH_BY_USE_NAME;
public static function getGroups(): array
{
return [FixturesHelper::GROUP_USE_NAME];
}
} }
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
namespace App\DataFixtures; namespace App\DataFixtures;
use App\Entity\User; use App\Entity\User;
use App\Helper\FixturesHelper;
use App\Helper\UserHelper; use App\Helper\UserHelper;
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class UserFixtures extends \Doctrine\Bundle\FixturesBundle\Fixture class UserFixtures extends \Doctrine\Bundle\FixturesBundle\Fixture implements FixtureGroupInterface
{ {
/** /**
* @var UserPasswordEncoderInterface * @var UserPasswordEncoderInterface
...@@ -19,6 +21,11 @@ class UserFixtures extends \Doctrine\Bundle\FixturesBundle\Fixture ...@@ -19,6 +21,11 @@ class UserFixtures extends \Doctrine\Bundle\FixturesBundle\Fixture
$this->encode = $encoder; $this->encode = $encoder;
} }
public static function getGroups(): array
{
return [FixturesHelper::GROUP_USE_NAME, FixturesHelper::GROUP_CIVIL_NAME];
}
/** /**
* @inheritDoc * @inheritDoc
*/ */
......
...@@ -87,6 +87,11 @@ class Person extends AbstractPerson ...@@ -87,6 +87,11 @@ class Person extends AbstractPerson
*/ */
private $helpCode; private $helpCode;
/**
* @ORM\Column(name="date_deces", type="date")
*/
private $deathDate;
public function getId(): ?int public function getId(): ?int
{ {
return $this->id; return $this->id;
...@@ -259,4 +264,16 @@ class Person extends AbstractPerson ...@@ -259,4 +264,16 @@ class Person extends AbstractPerson
return $this; return $this;
} }
public function getDeathDate(): ?\DateTimeInterface
{
return $this->deathDate;
}
public function setDeathDate(?\DateTimeInterface $deathDate): self
{
$this->deathDate = $deathDate;
return $this;
}
} }
...@@ -158,6 +158,21 @@ class SettingsType extends AbstractType ...@@ -158,6 +158,21 @@ class SettingsType extends AbstractType
'label' => 'settings.searchByName.label', 'label' => 'settings.searchByName.label',
] ]
) )
->add(
'deathAlert',
CheckboxType::class,
[
'required' => false,
'label' => 'settings.deathAlert'
]
)->add(
'deathAlertMail',
TextType::class,
[
'required' => false,
'label' => 'settings.deathAlertMail',
]
)
->add( ->add(
'mailSignature', 'mailSignature',
TextareaType::class, TextareaType::class,
......
...@@ -27,6 +27,7 @@ class DateToStringTransformer implements DataTransformerInterface ...@@ -27,6 +27,7 @@ class DateToStringTransformer implements DataTransformerInterface
public function reverseTransform($dateString) public function reverseTransform($dateString)
{ {
$date = \DateTime::createFromFormat('d/m/Y', $dateString); $date = \DateTime::createFromFormat('d/m/Y', $dateString);
$date->setTime(0, 0, 0);
if (!$date) { if (!$date) {
$failure = new TransformationFailedException(); $failure = new TransformationFailedException();
......
<?php
namespace App\Helper;
class FixturesHelper
{
const GROUP_USE_NAME = 'use_name';
const GROUP_CIVIL_NAME = 'civil_name';
const GROUP_USERS = 'users';
}
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20200618122432 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE individu ADD date_deces DATE DEFAULT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE individu DROP date_deces');
}
}
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
{% form_theme settingsForm 'default/form/fields.html.twig' %} {% form_theme settingsForm 'default/form/fields.html.twig' %}
{% block body %} {% block body %}
<div class="container"> <div class="container">
<h1>{% trans %}Paramètres de l'application{% endtrans %}</h1> <h1>{% trans %}Paramètres de l'application{% endtrans %}</h1>
<p class="title-notice notice">{% trans %}Tous les champs comportants * sont obligatoires.{% endtrans %}</p> <p class="title-notice notice">{% trans %}Tous les champs comportants * sont obligatoires.{% endtrans %}</p>
...@@ -27,6 +28,8 @@ ...@@ -27,6 +28,8 @@
{{ input_checkbox(settingsForm.soundexSearch) }} {{ input_checkbox(settingsForm.soundexSearch) }}
{{ input_field(settingsForm.connectionAttempts) }} {{ input_field(settingsForm.connectionAttempts) }}
{{ input_checkbox(settingsForm.searchByName) }} {{ input_checkbox(settingsForm.searchByName) }}
{{ input_checkbox(settingsForm.deathAlert) }}
{{ input_field(settingsForm.deathAlertMail) }}
</div> </div>
<h2>{% trans %}Paramètres des mails système{% endtrans %}</h2> <h2>{% trans %}Paramètres des mails système{% endtrans %}</h2>
......
<p>Alerte décès signalé par l'Etude de Maître {{ userName }} ({{ userEmail }}) </p>
<p>nom : {{ ('person.title.' ~ gender)|trans }} {{ firstName }} {{ useName }} {{ ('person.birth.' ~ gender)|trans }} {% if civilName %}({{ civilName }}){% endif%} le {{ birthDate|date("d/m/Y") }}</p>
<p>Décès : {{ deathDate|date("d/m/Y") }} à {{ deathLocation }}</p>
...@@ -4,6 +4,7 @@ namespace App\Tests\UnitTests\Controller; ...@@ -4,6 +4,7 @@ namespace App\Tests\UnitTests\Controller;
use App\Controller\SearchController; use App\Controller\SearchController;
use App\Data\SearchData; use App\Data\SearchData;
use App\Data\SettingsData;
use App\Entity\Person; use App\Entity\Person;
use App\Helper\SearchHelper; use App\Helper\SearchHelper;
use App\Service\SettingsDataService; use App\Service\SettingsDataService;
...@@ -33,6 +34,11 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase ...@@ -33,6 +34,11 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase
*/ */
protected $settingsDataService; protected $settingsDataService;
/**
* @var SettingsData
*/
protected $settingsData;
/** /**
* Test recherche d'une personne connue, aide récupérable * Test recherche d'une personne connue, aide récupérable
*/ */
...@@ -117,6 +123,18 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase ...@@ -117,6 +123,18 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase
$this->searchNotFindRequestInProgressPerson(true); $this->searchNotFindRequestInProgressPerson(true);
} }
/**
* Test alerte décès
*/
public function testDeathAlert()
{
// Test qui doit déclencher une alerte décès
$this->searchDeathAlertPerson(true);
// Test qui ne doit pas déclencher une alerte décès
$this->searchDeathAlertPerson(false);
}
abstract protected function initSettingsDataService(); abstract protected function initSettingsDataService();
/** /**
...@@ -376,6 +394,64 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase ...@@ -376,6 +394,64 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase
$this->assertSame(1, $countPersons); $this->assertSame(1, $countPersons);
} }
/**
* @param bool $needSendDeathAlert
*
* @throws \ReflectionException
*/
private function searchDeathAlertPerson(bool $needSendDeathAlert = true)
{
$this->settingsData->setDeathAlert(true);
$this->settingsData->setDeathAlertMail('notaires@deptnot.test');
$this->initSettingsDataService();