mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
List duplicate persons
Signed-off-by: Mathieu Jaumotte <mathieu.jaumotte@champs-libres.coop> Signed-off-by: Mathieu Jaumotte <mathieu.jaumotte@champs-libres.coop>
This commit is contained in:
parent
0cc951b296
commit
728ea73bdf
@ -0,0 +1,141 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Entity\PersonNotDuplicate;
|
||||||
|
use Chill\PersonBundle\Form\PersonConfimDuplicateType;
|
||||||
|
use Chill\PersonBundle\Repository\PersonRepository;
|
||||||
|
use Chill\PersonBundle\Search\SimilarPersonMatcher;
|
||||||
|
use http\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
class PersonDuplicateController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Chill\PersonBundle\Search\SimilarPersonMatcher
|
||||||
|
*/
|
||||||
|
private $similarPersonMatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Symfony\Component\Translation\TranslatorInterface
|
||||||
|
*/
|
||||||
|
private $translator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Chill\PersonBundle\Repository\PersonRepository
|
||||||
|
*/
|
||||||
|
private $personRepository;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
SimilarPersonMatcher $similarPersonMatcher,
|
||||||
|
TranslatorInterface $translator,
|
||||||
|
PersonRepository $personRepository
|
||||||
|
) {
|
||||||
|
$this->similarPersonMatcher = $similarPersonMatcher;
|
||||||
|
$this->translator = $translator;
|
||||||
|
$this->personRepository = $personRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function viewAction($person_id)
|
||||||
|
{
|
||||||
|
$person = $this->_getPerson($person_id);
|
||||||
|
if ($person === null) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found on this server");
|
||||||
|
}
|
||||||
|
|
||||||
|
$duplicatePersons = $this->similarPersonMatcher->matchPerson($person, 0.5);
|
||||||
|
|
||||||
|
return $this->render('ChillPersonBundle:PersonDuplicate:view.html.twig', [
|
||||||
|
"person" => $person,
|
||||||
|
'duplicatePersons' => $duplicatePersons
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function confirmAction($person_id, $person2_id, Request $request)
|
||||||
|
{
|
||||||
|
if ($person_id === $person2_id) {
|
||||||
|
throw new InvalidArgumentException('Can not merge same person');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($person_id > $person2_id) {
|
||||||
|
$tmpId = $person2_id;
|
||||||
|
$person2_id = $person_id;
|
||||||
|
$person_id = $tmpId;
|
||||||
|
unset($tmpId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = $this->_getPerson($person_id);
|
||||||
|
if ($person === null) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found on this server");
|
||||||
|
}
|
||||||
|
|
||||||
|
$person2 = $this->_getPerson($person2_id);
|
||||||
|
if ($person2 === null) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person2_id not"
|
||||||
|
. " found on this server");
|
||||||
|
}
|
||||||
|
|
||||||
|
$form = $this->createForm(PersonConfimDuplicateType::class);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
dd('todo');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('ChillPersonBundle:PersonDuplicate:confirm.html.twig', [
|
||||||
|
'person' => $person,
|
||||||
|
'person2' => $person2,
|
||||||
|
'form' => $form->createView(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function notDuplicateAction($person_id, $person2_id)
|
||||||
|
{
|
||||||
|
if ($person_id === $person2_id) {
|
||||||
|
throw new InvalidArgumentException('Can not merge same person');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($person_id > $person2_id) {
|
||||||
|
$tmpId = $person2_id;
|
||||||
|
$person2_id = $person_id;
|
||||||
|
$person_id = $tmpId;
|
||||||
|
unset($tmpId);
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = $this->_getPerson($person_id);
|
||||||
|
if ($person === null) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found on this server");
|
||||||
|
}
|
||||||
|
|
||||||
|
$person2 = $this->_getPerson($person2_id);
|
||||||
|
if ($person2 === null) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person2_id not"
|
||||||
|
. " found on this server");
|
||||||
|
}
|
||||||
|
|
||||||
|
$personNotDuplicate = new PersonNotDuplicate();
|
||||||
|
$personNotDuplicate->setPerson1($person);
|
||||||
|
$personNotDuplicate->setPerson2($person2);
|
||||||
|
$personNotDuplicate->setUser($this->getUser());
|
||||||
|
|
||||||
|
$this->getDoctrine()->getManager()->persist($personNotDuplicate);
|
||||||
|
$this->getDoctrine()->getManager()->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_duplicate_view', ['person_id' => $person->getId()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* easy getting a person by his id
|
||||||
|
*/
|
||||||
|
private function _getPerson($id): ?Person
|
||||||
|
{
|
||||||
|
return $this->personRepository->find($id);
|
||||||
|
}
|
||||||
|
}
|
107
src/Bundle/ChillPersonBundle/Entity/PersonNotDuplicate.php
Normal file
107
src/Bundle/ChillPersonBundle/Entity/PersonNotDuplicate.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Entity;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PersonNotDuplicate
|
||||||
|
*
|
||||||
|
* @ORM\Table(name="chill_person_not_duplicate")
|
||||||
|
* @ORM\Entity()
|
||||||
|
*/
|
||||||
|
class PersonNotDuplicate
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The person's id
|
||||||
|
* @var integer
|
||||||
|
*
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Person
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person")
|
||||||
|
*/
|
||||||
|
private $person1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Person
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person")
|
||||||
|
*/
|
||||||
|
private $person2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \DateTime
|
||||||
|
* @ORM\Column(type="datetime")
|
||||||
|
*/
|
||||||
|
private $date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User
|
||||||
|
*
|
||||||
|
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\User")
|
||||||
|
*/
|
||||||
|
private $user;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->date = new \DateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setId($id)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPerson1()
|
||||||
|
{
|
||||||
|
return $this->person1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPerson1(Person $person1)
|
||||||
|
{
|
||||||
|
$this->person1 = $person1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPerson2()
|
||||||
|
{
|
||||||
|
return $this->person2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPerson2(Person $person2)
|
||||||
|
{
|
||||||
|
$this->person2 = $person2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDate()
|
||||||
|
{
|
||||||
|
return $this->date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDate(\DateTime $date)
|
||||||
|
{
|
||||||
|
$this->date = $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser()
|
||||||
|
{
|
||||||
|
return $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUser(User $user)
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
|
class PersonConfimDuplicateType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param FormBuilderInterface $builder
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('confirm', CheckboxType::class, [
|
||||||
|
'label' => 'Je confirme la fusion de ces 2 personnes',
|
||||||
|
'mapped' => false,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getBlockPrefix()
|
||||||
|
{
|
||||||
|
return 'chill_personbundle_person_confirm_duplicate';
|
||||||
|
}
|
||||||
|
}
|
@ -63,6 +63,16 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
->setExtras([
|
->setExtras([
|
||||||
'order' => 50
|
'order' => 50
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$menu->addChild($this->translator->trans('Person duplicate'), [
|
||||||
|
'route' => 'chill_person_duplicate_view',
|
||||||
|
'routeParameters' => [
|
||||||
|
'person_id' => $parameters['person']->getId()
|
||||||
|
]
|
||||||
|
])
|
||||||
|
->setExtras([
|
||||||
|
'order' => 51
|
||||||
|
]);
|
||||||
|
|
||||||
if ($this->showAccompanyingPeriod === 'visible') {
|
if ($this->showAccompanyingPeriod === 'visible') {
|
||||||
$menu->addChild($this->translator->trans('Accompanying period list'), [
|
$menu->addChild($this->translator->trans('Accompanying period list'), [
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
{% extends "@ChillPerson/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = 'chill_person_duplicate' %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'Person duplicate'|trans|capitalize ~ ' ' ~ person.firstName|capitalize ~
|
||||||
|
' ' ~ person.lastName }}{% endblock %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
<h2>Ancien dossier</h2>
|
||||||
|
{{ person2 }}
|
||||||
|
<a class="sc-button bt-show" target="_blank" href="{{ path('chill_person_view', { person_id : person2.id }) }}"></a>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Nouveau Dossier</h2>
|
||||||
|
{{ person }}
|
||||||
|
<a class="sc-button bt-show" target="_blank" href="{{ path('chill_person_view', { person_id : person.id }) }}"></a>
|
||||||
|
|
||||||
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
{{ form_rest(form) }}
|
||||||
|
|
||||||
|
<ul class="grid-12 sticky-form-buttons record_actions ">
|
||||||
|
<li class="cancel">
|
||||||
|
<a href="{{ path('chill_person_duplicate_view', {'person_id' : person.id}) }}" class="sc-button grey center margin-5">
|
||||||
|
<i class="fa fa-arrow-left"></i>
|
||||||
|
{{ 'Return'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="sc-button bt-save" type="submit">{{ 'Confirm'|trans }}</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -0,0 +1,65 @@
|
|||||||
|
{% extends "@ChillPerson/layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = 'chill_person_duplicate' %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'Person duplicate'|trans|capitalize ~ ' ' ~ person.firstName|capitalize ~
|
||||||
|
' ' ~ person.lastName }}{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
|
||||||
|
<h2>{{ title|default('Person duplicate')|trans }}</h2>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="chill-red">{% trans %}Name{% endtrans %}</th>
|
||||||
|
<th class="chill-green">{% trans %}Date of birth{% endtrans %}</th>
|
||||||
|
<th class="chill-orange">{% trans %}Nationality{% endtrans %}</th>
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
{% for duplicatePerson in duplicatePersons %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% set is_open = duplicatePerson.isOpen() %}
|
||||||
|
<a href="{{ path('chill_person_view', { person_id : duplicatePerson.getId }) }}" {% if chill_person.fields.accompanying_period == 'visible' %}{% if is_open %} alt="{{ 'An accompanying period is open'|trans|e('html_attr') }}"{% else %} alt="{{ 'Any accompanying periods are open'|trans|e('html_attr') }}" {% endif %}{% endif %}>
|
||||||
|
{{ duplicatePerson|chill_entity_render_box }}
|
||||||
|
{% apply spaceless %}
|
||||||
|
{% if chill_person.fields.accompanying_period == 'visible' %}
|
||||||
|
{% if is_open == false %}
|
||||||
|
<i class="fa fa-lock" ></i>
|
||||||
|
{% else %}
|
||||||
|
<i class="fa fa-unlock" ></i>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endapply %}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if duplicatePerson.birthdate is not null %}
|
||||||
|
{{ duplicatePerson.birthdate|format_date('long') }}
|
||||||
|
{% else %}
|
||||||
|
{{ 'Unknown date of birth'|trans }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if duplicatePerson.nationality is not null %}
|
||||||
|
{{ duplicatePerson.nationality.name|localize_translatable_string }}
|
||||||
|
{% else %}
|
||||||
|
{{ 'Without nationality'|trans }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li><a class="sc-button bt-show" target="_blank" href="{{ path('chill_person_view', { person_id : duplicatePerson.id }) }}"></a></li>
|
||||||
|
<li><a class="sc-button bt-duplicate" href="{{ path('chill_person_duplicate_confirm', { person_id : person.id, person2_id : duplicatePerson.id }) }}"></a></li>
|
||||||
|
<li><a class="sc-button bt-not-duplicate" href="{{ path('chill_person_duplicate_not_duplicate', {person_id : person.id, person2_id : duplicatePerson.id}) }}"></a></li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
@ -61,35 +61,32 @@ class SimilarPersonMatcher
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function matchPerson(Person $person)
|
public function matchPerson(Person $person, $precision = 0.15)
|
||||||
{
|
{
|
||||||
$centers = $this->authorizationHelper
|
$centers = $this->authorizationHelper->getReachableCenters(
|
||||||
->getReachableCenters(
|
$this->tokenStorage->getToken()->getUser(),
|
||||||
$this->tokenStorage->getToken()->getUser(),
|
new Role(PersonVoter::SEE)
|
||||||
new Role(PersonVoter::SEE)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
$dql = 'SELECT p from ChillPersonBundle:Person p WHERE'
|
$dql = 'SELECT p from ChillPersonBundle:Person p '
|
||||||
. ' ('
|
. ' WHERE ('
|
||||||
. ' UNACCENT(LOWER(p.firstName)) LIKE UNACCENT(LOWER(:firstName)) '
|
. ' SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) >= :precision '
|
||||||
. ' OR UNACCENT(LOWER(p.lastName)) LIKE UNACCENT(LOWER(:lastName)) '
|
. ' OR SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullNameInverted))) >= :precision '
|
||||||
. ' OR UNACCENT(LOWER(p.firstName)) LIKE UNACCENT(LOWER(:lastName)) '
|
|
||||||
. ' OR UNACCENT(LOWER(p.lastName)) LIKE UNACCENT(LOWER(:firstName)) '
|
|
||||||
. ' OR SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) >= 0.15 '
|
|
||||||
. ' ) '
|
. ' ) '
|
||||||
. ' AND p.center IN (:centers)'
|
. ' AND p.center IN (:centers)'
|
||||||
|
. ' AND p.id != :personId'
|
||||||
. ' ORDER BY SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) DESC '
|
. ' ORDER BY SIMILARITY(p.fullnameCanonical, UNACCENT(LOWER(:fullName))) DESC '
|
||||||
;
|
;
|
||||||
|
|
||||||
$query =
|
$query = $this->em
|
||||||
$this->em
|
|
||||||
->createQuery($dql)
|
->createQuery($dql)
|
||||||
->setParameter('firstName', $person->getFirstName())
|
|
||||||
->setParameter('lastName', $person->getLastName())
|
|
||||||
->setParameter('fullName', $person->getFirstName() . ' ' . $person->getLastName())
|
->setParameter('fullName', $person->getFirstName() . ' ' . $person->getLastName())
|
||||||
|
->setParameter('fullNameInverted', $person->getLastName() . ' ' . $person->getFirstName())
|
||||||
->setParameter('centers', $centers)
|
->setParameter('centers', $centers)
|
||||||
;
|
->setParameter('personId', $person->getId())
|
||||||
|
->setParameter('precision', $precision)
|
||||||
|
;
|
||||||
|
|
||||||
return $query->getResult();
|
return $query->getResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,10 @@ chill_person_admin_redirect_to_admin_index:
|
|||||||
order: 0
|
order: 0
|
||||||
label: Main admin menu
|
label: Main admin menu
|
||||||
|
|
||||||
|
chill_person_duplicate_view:
|
||||||
|
path: /{_locale}/person/{person_id}/duplicate/view
|
||||||
|
controller: Chill\PersonBundle\Controller\PersonDuplicateController::viewAction
|
||||||
|
|
||||||
chill_person_closingmotive_admin:
|
chill_person_closingmotive_admin:
|
||||||
path: /{_locale}/admin/closing-motive
|
path: /{_locale}/admin/closing-motive
|
||||||
controller: cscrud_closing_motive_controller:index
|
controller: cscrud_closing_motive_controller:index
|
||||||
@ -107,6 +111,10 @@ chill_person_closingmotive_admin:
|
|||||||
order: 90
|
order: 90
|
||||||
label: 'person_admin.closing motives'
|
label: 'person_admin.closing motives'
|
||||||
|
|
||||||
|
chill_person_duplicate_confirm:
|
||||||
|
path: /{_locale}/person/{person_id}/duplicate/{person2_id}/confirm
|
||||||
|
controller: Chill\PersonBundle\Controller\PersonDuplicateController::confirmAction
|
||||||
|
|
||||||
chill_person_maritalstatus_admin:
|
chill_person_maritalstatus_admin:
|
||||||
path: /{_locale}/admin/marital-status
|
path: /{_locale}/admin/marital-status
|
||||||
controller: cscrud_marital_status_controller:index
|
controller: cscrud_marital_status_controller:index
|
||||||
@ -114,4 +122,8 @@ chill_person_maritalstatus_admin:
|
|||||||
menus:
|
menus:
|
||||||
admin_person:
|
admin_person:
|
||||||
order: 120
|
order: 120
|
||||||
label: 'person_admin.marital status'
|
label: 'person_admin.marital status'
|
||||||
|
|
||||||
|
chill_person_duplicate_not_duplicate:
|
||||||
|
path: /{_locale}/person/{person_id}/duplicate/{person2_id}/not-duplicate
|
||||||
|
controller: Chill\PersonBundle\Controller\PersonDuplicateController::notDuplicateAction
|
||||||
|
@ -20,5 +20,12 @@ services:
|
|||||||
arguments:
|
arguments:
|
||||||
$eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface'
|
$eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface'
|
||||||
tags: ['controller.service_arguments']
|
tags: ['controller.service_arguments']
|
||||||
|
|
||||||
Chill\PersonBundle\Controller\AdminController: ~
|
Chill\PersonBundle\Controller\AdminController: ~
|
||||||
|
|
||||||
|
Chill\PersonBundle\Controller\PersonDuplicateController:
|
||||||
|
arguments:
|
||||||
|
$similarPersonMatcher: '@Chill\PersonBundle\Search\SimilarPersonMatcher'
|
||||||
|
$translator: '@Symfony\Component\Translation\TranslatorInterface'
|
||||||
|
$personRepository: '@Chill\PersonBundle\Repository\PersonRepository'
|
||||||
|
tags: ['controller.service_arguments']
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Application\Migrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20210128152747 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->addSql('CREATE SEQUENCE chill_person_not_duplicate_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||||
|
$this->addSql('CREATE TABLE chill_person_not_duplicate (id INT NOT NULL, person1_id INT DEFAULT NULL, person2_id INT DEFAULT NULL, user_id INT DEFAULT NULL, date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_BD211EE23EF5821B ON chill_person_not_duplicate (person1_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_BD211EE22C402DF5 ON chill_person_not_duplicate (person2_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_BD211EE2A76ED395 ON chill_person_not_duplicate (user_id)');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_not_duplicate ADD CONSTRAINT FK_BD211EE23EF5821B FOREIGN KEY (person1_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_not_duplicate ADD CONSTRAINT FK_BD211EE22C402DF5 FOREIGN KEY (person2_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_not_duplicate ADD CONSTRAINT FK_BD211EE2A76ED395 FOREIGN KEY (user_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema) : void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP SEQUENCE chill_person_not_duplicate_id_seq CASCADE');
|
||||||
|
$this->addSql('DROP TABLE chill_person_not_duplicate');
|
||||||
|
}
|
||||||
|
}
|
@ -66,6 +66,7 @@ Reset: 'Remise à zéro'
|
|||||||
'Create accompanying period': 'Create accompanying period'
|
'Create accompanying period': 'Create accompanying period'
|
||||||
'Closing motive': 'Motif de clôture'
|
'Closing motive': 'Motif de clôture'
|
||||||
'Person details': 'Détails de la personne'
|
'Person details': 'Détails de la personne'
|
||||||
|
'Person duplicate': 'Find duplicate'
|
||||||
|
|
||||||
Create an accompanying period: Create an accompanying period
|
Create an accompanying period: Create an accompanying period
|
||||||
'Create': Create
|
'Create': Create
|
||||||
|
@ -119,6 +119,7 @@ Update accompanying period: Mettre à jour une période d'accompagnement
|
|||||||
"Period not opened : form is invalid": "La période n'a pas été ouverte: le formulaire est invalide."
|
"Period not opened : form is invalid": "La période n'a pas été ouverte: le formulaire est invalide."
|
||||||
'Closing motive': 'Motif de clôture'
|
'Closing motive': 'Motif de clôture'
|
||||||
'Person details': 'Détails de la personne'
|
'Person details': 'Détails de la personne'
|
||||||
|
'Person duplicate': 'Trouver des doublons'
|
||||||
'Update details for %name%': 'Modifier détails de %name%'
|
'Update details for %name%': 'Modifier détails de %name%'
|
||||||
Any accompanying periods are open: Aucune période d'accompagnement ouverte
|
Any accompanying periods are open: Aucune période d'accompagnement ouverte
|
||||||
An accompanying period is open: Une période d'accompagnement est ouverte
|
An accompanying period is open: Une période d'accompagnement est ouverte
|
||||||
|
Loading…
x
Reference in New Issue
Block a user