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 {
sh "composer config cache-dir '${env.WORKSPACE}/.cache/.composer'"
sh 'composer install --no-progress --no-suggest --no-interaction --no-scripts'
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 'chown -R www-data: .'
}
......
This diff is collapsed.
......@@ -71,7 +71,6 @@ class SearchController extends BaseController
) {
$searchData = new SearchData();
$persons = null;
$sendMailToInstructor = true;
$form = $this->createForm(SearchType::class, $searchData);
$form->handleRequest($request);
......@@ -82,6 +81,7 @@ class SearchController extends BaseController
$personRepository = $entityManager->getRepository(Person::class);
$useSoundex = $this->settingsData->hasSoundexSearch();
$person = null;
$searchStatus = SearchHelper::SEARCH_STATUS_NOTFIND;
$sendMailToInstructor = true;
[$searchStatus, $person] = $this->searchPerson($personRepository, $searchData, $useSoundex);
......@@ -103,6 +103,9 @@ class SearchController extends BaseController
$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);
if ($sendMailToInstructor) {
......@@ -355,19 +358,19 @@ class SearchController extends BaseController
$mailSubject = $this->translator->trans(
'searchResultMail.subject.default',
[
'%appName%' => $this->settingsData->getAppName(),
'%appName%' => $this->settingsData->getAppName(),
'%recipient%' => $searchData->getRecipient(),
'%firstName%' => $searchData->getFirstName(),
'%name%' => $searchData->getName($this->settingsData),
'%name%' => $searchData->getName($this->settingsData),
]
);
} else {
$mailSubject = $this->translator->trans(
'searchResultMail.subject.norecipient',
[
'%appName%' => $this->settingsData->getAppName(),
'%appName%' => $this->settingsData->getAppName(),
'%firstName%' => $searchData->getFirstName(),
'%name%' => $searchData->getName($this->settingsData),
'%name%' => $searchData->getName($this->settingsData),
]
);
}
......@@ -391,9 +394,9 @@ class SearchController extends BaseController
case SearchHelper::SEARCH_STATUS_FIND_NOTREC:
$person = $personService->getPerson($searchLog->getPerson());
$mailParametersBdd = [
'firstNameBdd' => $person->getFirstName(),
'nameBdd' => strtoupper($person->getName($this->settingsData)),
'birthDateBdd' => $person->getBirthDate(),
'firstNameBdd' => $person->getFirstName(),
'nameBdd' => strtoupper($person->getName($this->settingsData)),
'birthDateBdd' => $person->getBirthDate(),
];
$mailParameters = array_merge($mailParameters, $mailParametersBdd);
$mailTemplate = 'emails/search_find.html.twig';
......@@ -573,4 +576,79 @@ class SearchController extends BaseController
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
*/
protected $searchByName = SearchHelper::SEARCH_BY_USE_NAME;
/**
* @var bool
* @BooleanSetting
*/
protected $deathAlert = false;
/**
* @var string
*/
protected $deathAlertMail;
/**
* @var string
*/
......@@ -400,6 +411,45 @@ class SettingsData
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
......
......@@ -59,6 +59,12 @@ abstract class AbstractPersonFixtures extends \Doctrine\Bundle\FixturesBundle\Fi
$person->setLabel(trim($personData['libelle']));
$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);
}
......
......@@ -2,9 +2,16 @@
namespace App\DataFixtures;
use App\Helper\FixturesHelper;
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;
public static function getGroups(): array
{
return [FixturesHelper::GROUP_CIVIL_NAME];
}
}
......@@ -2,9 +2,16 @@
namespace App\DataFixtures;
use App\Helper\FixturesHelper;
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;
public static function getGroups(): array
{
return [FixturesHelper::GROUP_USE_NAME];
}
}
......@@ -3,11 +3,13 @@
namespace App\DataFixtures;
use App\Entity\User;
use App\Helper\FixturesHelper;
use App\Helper\UserHelper;
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
use Doctrine\Persistence\ObjectManager;
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
......@@ -19,6 +21,11 @@ class UserFixtures extends \Doctrine\Bundle\FixturesBundle\Fixture
$this->encode = $encoder;
}
public static function getGroups(): array
{
return [FixturesHelper::GROUP_USE_NAME, FixturesHelper::GROUP_CIVIL_NAME];
}
/**
* @inheritDoc
*/
......
......@@ -87,6 +87,11 @@ class Person extends AbstractPerson
*/
private $helpCode;
/**
* @ORM\Column(name="date_deces", type="date")
*/
private $deathDate;
public function getId(): ?int
{
return $this->id;
......@@ -259,4 +264,16 @@ class Person extends AbstractPerson
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
'label' => 'settings.searchByName.label',
]
)
->add(
'deathAlert',
CheckboxType::class,
[
'required' => false,
'label' => 'settings.deathAlert'
]
)->add(
'deathAlertMail',
TextType::class,
[
'required' => false,
'label' => 'settings.deathAlertMail',
]
)
->add(
'mailSignature',
TextareaType::class,
......
......@@ -27,6 +27,7 @@ class DateToStringTransformer implements DataTransformerInterface
public function reverseTransform($dateString)
{
$date = \DateTime::createFromFormat('d/m/Y', $dateString);
$date->setTime(0, 0, 0);
if (!$date) {
$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 @@
{% form_theme settingsForm 'default/form/fields.html.twig' %}
{% block body %}
<div class="container">
<h1>{% trans %}Paramètres de l'application{% endtrans %}</h1>
<p class="title-notice notice">{% trans %}Tous les champs comportants * sont obligatoires.{% endtrans %}</p>
......@@ -27,6 +28,8 @@
{{ input_checkbox(settingsForm.soundexSearch) }}
{{ input_field(settingsForm.connectionAttempts) }}
{{ input_checkbox(settingsForm.searchByName) }}
{{ input_checkbox(settingsForm.deathAlert) }}
{{ input_field(settingsForm.deathAlertMail) }}
</div>
<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;
use App\Controller\SearchController;
use App\Data\SearchData;
use App\Data\SettingsData;
use App\Entity\Person;
use App\Helper\SearchHelper;
use App\Service\SettingsDataService;
......@@ -33,6 +34,11 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase
*/
protected $settingsDataService;
/**
* @var SettingsData
*/
protected $settingsData;
/**
* Test recherche d'une personne connue, aide récupérable
*/
......@@ -117,6 +123,18 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase
$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();
/**
......@@ -376,6 +394,64 @@ abstract class AbstractSearchControllerTest extends FixtureAwareTestCase
$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();
$searchData = new SearchData();
if ($needSendDeathAlert) {
$searchData->setDeathDate(\DateTime::createFromFormat('j/m/Y', '15/05/2019'));
} else {
$searchData->setDeathDate(\DateTime::createFromFormat('j/m/Y', '13/05/2019'));
}
$searchData->setDeathLocation('VILLEFRANCHE');
$searchData->setDeathCertificateDate(\DateTime::createFromFormat('j/m/Y', '10/02/2020'));
$searchData->setFirstName('Adrienne');
switch ($this->settingsDataService->getData()->getSearchByName()) {
case SearchHelper::SEARCH_BY_CIVIL_NAME:
$searchData->setCivilName('GENILLON');
$nameField = 'civilName';
break;
default:
$searchData->setUseName('GENILLON');
$nameField = 'useName';
}
$searchData->setBirthDate(\DateTime::createFromFormat('j/m/Y', '26/02/2001'));
$personRepository = $this->entityManager->getRepository(Person::class);
$findPerson = $personRepository->findOneBy(
[
'firstName' => 'Adrienne',
$nameField => 'GENILLON',
'birthDate' => \DateTime::createFromFormat('j/m/Y', '26/02/2001'),
]
);
$controller = new SearchController($this->settingsDataService, $this->translator, 'default');
/**
* @var string $searchStatus
* @var Person $person
*/
$hasDeathAlert = $this->invokeMethod(
$controller,
'sendDeathAlert',
[$findPerson, $searchData]
);
$this->assertSame(true, $hasDeathAlert);
}
/**
* Call protected/private method of a class.
*
......
......@@ -25,6 +25,8 @@ class SearchCivilNameControllerTest extends AbstractSearchControllerTest
$this->addFixture(new UserFixtures($encoder));
$this->addFixture(new PersonCivilNameFixtures());
$this->executeFixtures();
$this->settingsData = new SettingsData($this->settingService);
}
/**
......@@ -35,10 +37,9 @@ class SearchCivilNameControllerTest extends AbstractSearchControllerTest
*/
protected function initSettingsDataService()
{
$settingsData = new SettingsData($this->settingService);
$settingsData->setAppName('D&N');
$settingsData->setSearchByName(SearchHelper::SEARCH_BY_CIVIL_NAME);
$this->settingsData->setAppName('D&N');
$this->settingsData->setSearchByName(SearchHelper::SEARCH_BY_CIVIL_NAME);
$this->settingsDataService = new SettingsDataService($settingsData);
$this->settingsDataService = new SettingsDataService($this->settingsData);
}
}
......@@ -25,6 +25,8 @@ class SearchUseNameControllerTest extends AbstractSearchControllerTest
$this->addFixture(new UserFixtures($encoder));
$this->addFixture(new PersonUseNameFixtures());
$this->executeFixtures();
$this->settingsData = new SettingsData($this->settingService);
}
/**
......@@ -35,10 +37,9 @@ class SearchUseNameControllerTest extends AbstractSearchControllerTest
*/
protected function initSettingsDataService()
{
$settingsData = new SettingsData($this->settingService);
$settingsData->setAppName('D&N');
$settingsData->setSearchByName(SearchHelper::SEARCH_BY_USE_NAME);
$this->settingsData->setAppName('D&N');
$this->settingsData->setSearchByName(SearchHelper::SEARCH_BY_USE_NAME);
$this->settingsDataService = new SettingsDataService($settingsData);
$this->settingsDataService = new SettingsDataService($this->settingsData);
}
}
......@@ -68,6 +68,8 @@ settings:
label: "Recherche par nom"
1: "Nom d'usage"
2: "Nom d'état civil"
deathAlert: "Activer l'alerte décès"
deathAlertMail: "Mail de destination des alertes décès"
mailSignature: "Signature"
mailIntroduction: "Introduction"
mailNotaBene: "Nota Bene"
......@@ -211,6 +213,9 @@ searchResultMail:
default: "[%appName%] Notaire référent : %recipient% - Succession %firstName% %name%"
norecipient: "[%appName%] Succession %firstName% %name%"
hasRequest: "[%appName%] Instruction"
searchDeathAlertMail:
subject:
default: "[%appName%] Alerte décès"
formError:
date: "Mauvais format de date"
userLogs:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment