mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'create_gender_entity' into 'master'
Add gender entity See merge request Chill-Projet/chill-bundles!740
This commit is contained in:
commit
2b45a51f57
5
.changes/unreleased/Feature-20241030-095713.yaml
Normal file
5
.changes/unreleased/Feature-20241030-095713.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Introduce a gender entity
|
||||||
|
time: 2024-10-30T09:57:13.110347067+01:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
@ -59,7 +59,8 @@
|
|||||||
"vue-i18n": "^9.1.6",
|
"vue-i18n": "^9.1.6",
|
||||||
"vue-multiselect": "3.0.0-alpha.2",
|
"vue-multiselect": "3.0.0-alpha.2",
|
||||||
"vue-toast-notification": "^3.1.2",
|
"vue-toast-notification": "^3.1.2",
|
||||||
"vuex": "^4.0.0"
|
"vuex": "^4.0.0",
|
||||||
|
"bootstrap-icons": "^1.11.3"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"Firefox ESR"
|
"Firefox ESR"
|
||||||
|
@ -178,7 +178,7 @@ class CustomFieldsGroup
|
|||||||
*
|
*
|
||||||
* @return CustomFieldsGroup
|
* @return CustomFieldsGroup
|
||||||
*/
|
*/
|
||||||
public function setName($name)
|
public function setName(array|string $name)
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
class GenderApiController extends ApiController
|
||||||
|
{
|
||||||
|
protected function customizeQuery(string $action, Request $request, $query): void
|
||||||
|
{
|
||||||
|
$query
|
||||||
|
->andWhere(
|
||||||
|
$query->expr()->eq('e.active', "'TRUE'")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format)
|
||||||
|
{
|
||||||
|
return $query->addOrderBy('e.order', 'ASC');
|
||||||
|
}
|
||||||
|
}
|
26
src/Bundle/ChillMainBundle/Controller/GenderController.php
Normal file
26
src/Bundle/ChillMainBundle/Controller/GenderController.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
class GenderController extends CRUDController
|
||||||
|
{
|
||||||
|
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
|
||||||
|
{
|
||||||
|
$query->addOrderBy('e.order', 'ASC');
|
||||||
|
|
||||||
|
return parent::orderQuery($action, $query, $request, $paginator);
|
||||||
|
}
|
||||||
|
}
|
63
src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php
Normal file
63
src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\DataFixtures\ORM;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Entity\GenderEnum;
|
||||||
|
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||||
|
use Doctrine\Common\DataFixtures\AbstractFixture;
|
||||||
|
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
||||||
|
use Doctrine\Persistence\ObjectManager;
|
||||||
|
|
||||||
|
class LoadGenders extends AbstractFixture implements OrderedFixtureInterface
|
||||||
|
{
|
||||||
|
private array $genders = [
|
||||||
|
[
|
||||||
|
'label' => ['en' => 'man', 'fr' => 'homme'],
|
||||||
|
'genderTranslation' => GenderEnum::MALE,
|
||||||
|
'icon' => GenderIconEnum::MALE,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => ['en' => 'woman', 'fr' => 'femme'],
|
||||||
|
'genderTranslation' => GenderEnum::FEMALE,
|
||||||
|
'icon' => GenderIconEnum::FEMALE,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'label' => ['en' => 'neutral', 'fr' => 'neutre'],
|
||||||
|
'genderTranslation' => GenderEnum::NEUTRAL,
|
||||||
|
'icon' => GenderIconEnum::NEUTRAL,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function getOrder()
|
||||||
|
{
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function load(ObjectManager $manager)
|
||||||
|
{
|
||||||
|
echo "loading genders... \n";
|
||||||
|
|
||||||
|
foreach ($this->genders as $g) {
|
||||||
|
echo $g['label']['fr'].' ';
|
||||||
|
$new_g = new Gender();
|
||||||
|
$new_g->setGenderTranslation($g['genderTranslation']);
|
||||||
|
$new_g->setLabel($g['label']);
|
||||||
|
$new_g->setIcon($g['icon']);
|
||||||
|
|
||||||
|
$this->addReference('g_'.$g['genderTranslation']->value, $new_g);
|
||||||
|
$manager->persist($new_g);
|
||||||
|
}
|
||||||
|
|
||||||
|
$manager->flush();
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,8 @@ use Chill\MainBundle\Controller\CivilityApiController;
|
|||||||
use Chill\MainBundle\Controller\CivilityController;
|
use Chill\MainBundle\Controller\CivilityController;
|
||||||
use Chill\MainBundle\Controller\CountryApiController;
|
use Chill\MainBundle\Controller\CountryApiController;
|
||||||
use Chill\MainBundle\Controller\CountryController;
|
use Chill\MainBundle\Controller\CountryController;
|
||||||
|
use Chill\MainBundle\Controller\GenderApiController;
|
||||||
|
use Chill\MainBundle\Controller\GenderController;
|
||||||
use Chill\MainBundle\Controller\GeographicalUnitApiController;
|
use Chill\MainBundle\Controller\GeographicalUnitApiController;
|
||||||
use Chill\MainBundle\Controller\LanguageController;
|
use Chill\MainBundle\Controller\LanguageController;
|
||||||
use Chill\MainBundle\Controller\LocationController;
|
use Chill\MainBundle\Controller\LocationController;
|
||||||
@ -52,6 +54,7 @@ use Chill\MainBundle\Doctrine\Type\PointType;
|
|||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Entity\Civility;
|
use Chill\MainBundle\Entity\Civility;
|
||||||
use Chill\MainBundle\Entity\Country;
|
use Chill\MainBundle\Entity\Country;
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
use Chill\MainBundle\Entity\GeographicalUnitLayer;
|
use Chill\MainBundle\Entity\GeographicalUnitLayer;
|
||||||
use Chill\MainBundle\Entity\Language;
|
use Chill\MainBundle\Entity\Language;
|
||||||
use Chill\MainBundle\Entity\Location;
|
use Chill\MainBundle\Entity\Location;
|
||||||
@ -63,6 +66,7 @@ use Chill\MainBundle\Entity\UserJob;
|
|||||||
use Chill\MainBundle\Form\CenterType;
|
use Chill\MainBundle\Form\CenterType;
|
||||||
use Chill\MainBundle\Form\CivilityType;
|
use Chill\MainBundle\Form\CivilityType;
|
||||||
use Chill\MainBundle\Form\CountryType;
|
use Chill\MainBundle\Form\CountryType;
|
||||||
|
use Chill\MainBundle\Form\GenderType;
|
||||||
use Chill\MainBundle\Form\LanguageType;
|
use Chill\MainBundle\Form\LanguageType;
|
||||||
use Chill\MainBundle\Form\LocationFormType;
|
use Chill\MainBundle\Form\LocationFormType;
|
||||||
use Chill\MainBundle\Form\LocationTypeType;
|
use Chill\MainBundle\Form\LocationTypeType;
|
||||||
@ -485,6 +489,28 @@ class ChillMainExtension extends Extension implements
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'class' => Gender::class,
|
||||||
|
'name' => 'main_gender',
|
||||||
|
'base_path' => '/admin/main/gender',
|
||||||
|
'base_role' => 'ROLE_ADMIN',
|
||||||
|
'form_class' => GenderType::class,
|
||||||
|
'controller' => GenderController::class,
|
||||||
|
'actions' => [
|
||||||
|
'index' => [
|
||||||
|
'role' => 'ROLE_ADMIN',
|
||||||
|
'template' => '@ChillMain/Gender/index.html.twig',
|
||||||
|
],
|
||||||
|
'new' => [
|
||||||
|
'role' => 'ROLE_ADMIN',
|
||||||
|
'template' => '@ChillMain/Gender/new.html.twig',
|
||||||
|
],
|
||||||
|
'edit' => [
|
||||||
|
'role' => 'ROLE_ADMIN',
|
||||||
|
'template' => '@ChillMain/Gender/edit.html.twig',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'class' => Language::class,
|
'class' => Language::class,
|
||||||
'name' => 'main_language',
|
'name' => 'main_language',
|
||||||
@ -788,6 +814,21 @@ class ChillMainExtension extends Extension implements
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'class' => Gender::class,
|
||||||
|
'name' => 'gender',
|
||||||
|
'base_path' => '/api/1.0/main/gender',
|
||||||
|
'base_role' => 'ROLE_USER',
|
||||||
|
'controller' => GenderApiController::class,
|
||||||
|
'actions' => [
|
||||||
|
'_index' => [
|
||||||
|
'methods' => [
|
||||||
|
Request::METHOD_GET => true,
|
||||||
|
Request::METHOD_HEAD => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'class' => GeographicalUnitLayer::class,
|
'class' => GeographicalUnitLayer::class,
|
||||||
'controller' => GeographicalUnitApiController::class,
|
'controller' => GeographicalUnitApiController::class,
|
||||||
|
104
src/Bundle/ChillMainBundle/Entity/Gender.php
Normal file
104
src/Bundle/ChillMainBundle/Entity/Gender.php
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Entity;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Repository\GenderRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
#[Serializer\DiscriminatorMap(typeProperty: 'type', mapping: ['chill_main_gender' => Gender::class])]
|
||||||
|
#[ORM\Entity(repositoryClass: GenderRepository::class)]
|
||||||
|
#[ORM\Table(name: 'chill_main_gender')]
|
||||||
|
class Gender
|
||||||
|
{
|
||||||
|
#[Serializer\Groups(['read'])]
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[Serializer\Groups(['read'])]
|
||||||
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON)]
|
||||||
|
private array $label = [];
|
||||||
|
|
||||||
|
#[Serializer\Groups(['read'])]
|
||||||
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)]
|
||||||
|
private bool $active = true;
|
||||||
|
|
||||||
|
#[Assert\NotNull(message: 'You must choose a gender translation')]
|
||||||
|
#[Serializer\Groups(['read'])]
|
||||||
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, enumType: GenderEnum::class)]
|
||||||
|
private GenderEnum $genderTranslation;
|
||||||
|
|
||||||
|
#[Serializer\Groups(['read'])]
|
||||||
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, enumType: GenderIconEnum::class)]
|
||||||
|
private GenderIconEnum $icon;
|
||||||
|
|
||||||
|
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::FLOAT, name: 'ordering', nullable: true, options: ['default' => '0.0'])]
|
||||||
|
private float $order = 0;
|
||||||
|
|
||||||
|
public function getId(): int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabel(): array
|
||||||
|
{
|
||||||
|
return $this->label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLabel(array $label): void
|
||||||
|
{
|
||||||
|
$this->label = $label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isActive(): bool
|
||||||
|
{
|
||||||
|
return $this->active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setActive(bool $active): void
|
||||||
|
{
|
||||||
|
$this->active = $active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGenderTranslation(): GenderEnum
|
||||||
|
{
|
||||||
|
return $this->genderTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setGenderTranslation(GenderEnum $genderTranslation): void
|
||||||
|
{
|
||||||
|
$this->genderTranslation = $genderTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIcon(): GenderIconEnum
|
||||||
|
{
|
||||||
|
return $this->icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setIcon(GenderIconEnum $icon): void
|
||||||
|
{
|
||||||
|
$this->icon = $icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOrder(): float
|
||||||
|
{
|
||||||
|
return $this->order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOrder(float $order): void
|
||||||
|
{
|
||||||
|
$this->order = $order;
|
||||||
|
}
|
||||||
|
}
|
19
src/Bundle/ChillMainBundle/Entity/GenderEnum.php
Normal file
19
src/Bundle/ChillMainBundle/Entity/GenderEnum.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Entity;
|
||||||
|
|
||||||
|
enum GenderEnum: string
|
||||||
|
{
|
||||||
|
case MALE = 'man';
|
||||||
|
case FEMALE = 'woman';
|
||||||
|
case NEUTRAL = 'neutral';
|
||||||
|
}
|
21
src/Bundle/ChillMainBundle/Entity/GenderIconEnum.php
Normal file
21
src/Bundle/ChillMainBundle/Entity/GenderIconEnum.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Entity;
|
||||||
|
|
||||||
|
enum GenderIconEnum: string
|
||||||
|
{
|
||||||
|
case MALE = 'bi bi-gender-male';
|
||||||
|
case FEMALE = 'bi bi-gender-female';
|
||||||
|
case NEUTRAL = 'bi bi-gender-neuter';
|
||||||
|
case AMBIGUOUS = 'bi bi-gender-ambiguous';
|
||||||
|
case TRANS = 'bi bi-gender-trans';
|
||||||
|
}
|
64
src/Bundle/ChillMainBundle/Form/GenderType.php
Normal file
64
src/Bundle/ChillMainBundle/Form/GenderType.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Form;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Entity\GenderEnum;
|
||||||
|
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||||
|
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\NumberType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class GenderType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('label', TranslatableStringFormType::class, [
|
||||||
|
'required' => true,
|
||||||
|
])
|
||||||
|
->add('icon', EnumType::class, [
|
||||||
|
'class' => GenderIconEnum::class,
|
||||||
|
'choices' => GenderIconEnum::cases(),
|
||||||
|
'expanded' => true,
|
||||||
|
'multiple' => false,
|
||||||
|
'mapped' => true,
|
||||||
|
'choice_label' => fn (GenderIconEnum $enum) => '<i class="'.strtolower($enum->value).'"></i>',
|
||||||
|
'choice_value' => fn (?GenderIconEnum $enum) => null !== $enum ? $enum->value : null,
|
||||||
|
'label' => 'gender.admin.Select Gender Icon',
|
||||||
|
'label_html' => true,
|
||||||
|
])
|
||||||
|
->add('genderTranslation', EnumType::class, [
|
||||||
|
'class' => GenderEnum::class,
|
||||||
|
'choice_label' => fn (GenderEnum $enum) => $enum->value,
|
||||||
|
'label' => 'gender.admin.Select Gender Translation',
|
||||||
|
])
|
||||||
|
->add('active', ChoiceType::class, [
|
||||||
|
'choices' => [
|
||||||
|
'Active' => true,
|
||||||
|
'Inactive' => false,
|
||||||
|
],
|
||||||
|
])
|
||||||
|
->add('order', NumberType::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => Gender::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
47
src/Bundle/ChillMainBundle/Repository/GenderRepository.php
Normal file
47
src/Bundle/ChillMainBundle/Repository/GenderRepository.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Repository;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<Gender>
|
||||||
|
*/
|
||||||
|
class GenderRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, Gender::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findByActiveOrdered(): array
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('g')
|
||||||
|
->select('g')
|
||||||
|
->where('g.active = True')
|
||||||
|
->orderBy('g.order', 'ASC')
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findByGenderTranslation($gender): array
|
||||||
|
{
|
||||||
|
return $this->createQueryBuilder('g')
|
||||||
|
->select('g')
|
||||||
|
->where('g.genderTranslation = :gender')
|
||||||
|
->setParameter('gender', $gender)
|
||||||
|
->getQuery()
|
||||||
|
->getResult();
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import Modal from 'bootstrap/js/dist/modal';
|
|||||||
import Collapse from 'bootstrap/js/src/collapse';
|
import Collapse from 'bootstrap/js/src/collapse';
|
||||||
import Carousel from 'bootstrap/js/src/carousel';
|
import Carousel from 'bootstrap/js/src/carousel';
|
||||||
import Popover from 'bootstrap/js/src/popover';
|
import Popover from 'bootstrap/js/src/popover';
|
||||||
|
import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||||
|
|
||||||
//
|
//
|
||||||
// Carousel: ACHeaderSlider is a small slider used in banner of AccompanyingCourse Section
|
// Carousel: ACHeaderSlider is a small slider used in banner of AccompanyingCourse Section
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<i :class="gender.icon"></i>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
gender: Object
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
@ -38,7 +38,8 @@ const messages = {
|
|||||||
person: "Usager",
|
person: "Usager",
|
||||||
birthday: {
|
birthday: {
|
||||||
man: "Né le",
|
man: "Né le",
|
||||||
woman: "Née le"
|
woman: "Née le",
|
||||||
|
neutral: "Né·e le"
|
||||||
},
|
},
|
||||||
deathdate: "Date de décès",
|
deathdate: "Date de décès",
|
||||||
household_without_address: "Le ménage de l'usager est sans adresse",
|
household_without_address: "Le ménage de l'usager est sans adresse",
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% form_theme form _self %}
|
||||||
|
|
||||||
|
{% block _gender_icon_widget %}
|
||||||
|
{% for child in form %}
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
id="{{ child.vars.id }}"
|
||||||
|
name="{{ child.vars.full_name }}"
|
||||||
|
value="{{ child.vars.value }}"
|
||||||
|
{% if child.vars.checked %}checked="checked"{% endif %}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label for="{{ child.vars.id }}">{{ child.vars.label|raw }}</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block admin_content %}
|
||||||
|
{% set formId = crudMainFormId|default('crud_main_form') %}
|
||||||
|
|
||||||
|
{% block crud_content_header %}
|
||||||
|
<h1 class="mb-5">{{ ('crud.'~crud_name~'.title_edit')|trans }}</h1>
|
||||||
|
{% endblock crud_content_header %}
|
||||||
|
|
||||||
|
{% block crud_content_form %}
|
||||||
|
{{ form_start(form, { 'attr' : { 'id': formId } }) }}
|
||||||
|
|
||||||
|
{{ form_row(form.label) }}
|
||||||
|
{{ form_row(form.genderTranslation) }}
|
||||||
|
{{ form_row(form.icon) }}
|
||||||
|
{{ form_row(form.active) }}
|
||||||
|
{{ form_row(form.order) }}
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
{% block crud_content_after_form %}{% endblock %}
|
||||||
|
|
||||||
|
{% block crud_content_form_actions %}
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
{% block content_form_actions_back %}
|
||||||
|
<li class="cancel">
|
||||||
|
{# <a class="btn btn-cancel" href="{{ chill_return_path_or('chill_crud_'~crud_name~'_index') }}">#}
|
||||||
|
{# {{ 'Cancel'|trans }}#}
|
||||||
|
{# </a>#}
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content_form_actions_before %}{% endblock %}
|
||||||
|
{% block content_form_actions_delete %}
|
||||||
|
{% if chill_crud_action_exists(crud_name, 'delete') %}
|
||||||
|
{% if is_granted(chill_crud_config('role', crud_name, 'delete'), entity) %}
|
||||||
|
<li class="">
|
||||||
|
<a class="btn btn-small btn-delete" href="{{ chill_path_add_return_path('chill_crud_'~crud_name~'_delete', { 'id': entity.id }) }}"></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock content_form_actions_delete %}
|
||||||
|
{% block content_form_actions_save_and_close %}
|
||||||
|
<li class="">
|
||||||
|
<button type="submit" name="submit" value="save-and-close" class="btn btn-update" form="{{ formId }}">
|
||||||
|
{{ 'crud.edit.save_and_close'|trans }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content_form_actions_after %}{% endblock %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
{% endblock admin_content %}
|
@ -0,0 +1,46 @@
|
|||||||
|
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||||
|
|
||||||
|
{% block admin_content %}
|
||||||
|
{% embed '@ChillMain/CRUD/_index.html.twig' %}
|
||||||
|
{% block table_entities_thead_tr %}
|
||||||
|
<th>id</th>
|
||||||
|
<th>{{ 'label'|trans }}</th>
|
||||||
|
<th>{{ 'icon'|trans }}</th>
|
||||||
|
<th>{{ 'gender.genderTranslation'|trans }}</th>
|
||||||
|
<th>{{ 'active'|trans }}</th>
|
||||||
|
<th>{{ 'ordering'|trans }}</th>
|
||||||
|
<th></th>
|
||||||
|
{% endblock %}
|
||||||
|
{% block table_entities_tbody %}
|
||||||
|
{% for entity in entities %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ entity.id }}</td>
|
||||||
|
<td>{{ entity.label|localize_translatable_string }}</td>
|
||||||
|
<td>{{ entity.icon|chill_entity_render_box }}</td>
|
||||||
|
<td>{{ entity.genderTranslation.value }}</td>
|
||||||
|
<td style="text-align:center;">
|
||||||
|
{%- if entity.active -%}
|
||||||
|
<i class="fa fa-check-square-o"></i>
|
||||||
|
{%- else -%}
|
||||||
|
<i class="fa fa-square-o"></i>
|
||||||
|
{%- endif -%}
|
||||||
|
</td>
|
||||||
|
<td>{{ entity.order }}</td>
|
||||||
|
<td>
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a href="{{ chill_path_add_return_path('chill_crud_main_gender_edit', { 'id': entity.id}) }}" class="btn btn-sm btn-edit btn-mini"></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block actions_before %}
|
||||||
|
<li class='cancel'>
|
||||||
|
<a href="{{ path('chill_main_admin_central') }}" class="btn btn-cancel">{{'Back to the admin'|trans}}</a>
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% endembed %}
|
||||||
|
{% endblock %}
|
@ -0,0 +1,79 @@
|
|||||||
|
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% include('@ChillMain/CRUD/_new_title.html.twig') %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% form_theme form _self %}
|
||||||
|
|
||||||
|
{% block _gender_icon_widget %}
|
||||||
|
{% for child in form %}
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
id="{{ child.vars.id }}"
|
||||||
|
name="{{ child.vars.full_name }}"
|
||||||
|
value="{{ child.vars.value }}"
|
||||||
|
{% if child.vars.checked %}checked="checked"{% endif %}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<label for="{{ child.vars.id }}">{{ child.vars.label|raw }}</label>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block admin_content %}
|
||||||
|
{% set formId = crudMainFormId|default('crud_main_form') %}
|
||||||
|
|
||||||
|
{% block crud_content_header %}
|
||||||
|
<h1>{{ ('crud.' ~ crud_name ~ '.title_new')|trans({'%crud_name%' : crud_name }) }}</h1>
|
||||||
|
{% endblock crud_content_header %}
|
||||||
|
|
||||||
|
{% block crud_content_form %}
|
||||||
|
{{ form_start(form, { 'attr' : { 'id': formId } }) }}
|
||||||
|
{{ form_row(form.label) }}
|
||||||
|
{{ form_row(form.genderTranslation) }}
|
||||||
|
{{ form_row(form.icon) }}
|
||||||
|
{{ form_row(form.active) }}
|
||||||
|
{{ form_row(form.order) }}
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% block crud_content_after_form %}{% endblock %}
|
||||||
|
|
||||||
|
{% block crud_content_form_actions %}
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
|
{% block content_form_actions_back %}
|
||||||
|
<li class="cancel">
|
||||||
|
<a class="btn btn-cancel" href="{{ chill_return_path_or('chill_crud_'~crud_name~'_index') }}">
|
||||||
|
{{ 'Cancel'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content_form_actions_save_and_close %}
|
||||||
|
<li class="">
|
||||||
|
<button type="submit" name="submit" value="save-and-close" class="btn btn-create" form="{{ formId }}">
|
||||||
|
{{ 'crud.new.save_and_close'|trans }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content_form_actions_save_and_show %}
|
||||||
|
<li class="">
|
||||||
|
<button type="submit" name="submit" value="save-and-show" class="btn btn-create" form="{{ formId }}">
|
||||||
|
{{ 'crud.new.save_and_show'|trans }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content_form_actions_save_and_new %}
|
||||||
|
<li class="">
|
||||||
|
<button type="submit" name="submit" value="save-and-new" class="btn btn-create" form="{{ formId }}">
|
||||||
|
{{ 'crud.new.save_and_new'|trans }}
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
{% endblock %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% endblock admin_content %}
|
@ -62,12 +62,12 @@ abstract class AbstractSearch implements SearchInterface
|
|||||||
$recomposed .= ' '.$term.':';
|
$recomposed .= ' '.$term.':';
|
||||||
$containsSpace = str_contains((string) $terms[$term], ' ');
|
$containsSpace = str_contains((string) $terms[$term], ' ');
|
||||||
|
|
||||||
if ($containsSpace) {
|
if ($containsSpace || is_numeric($terms[$term])) {
|
||||||
$recomposed .= '"';
|
$recomposed .= '"';
|
||||||
}
|
}
|
||||||
$recomposed .= (false === mb_stristr(' ', (string) $terms[$term])) ? $terms[$term] : '('.$terms[$term].')';
|
$recomposed .= (false === mb_stristr(' ', (string) $terms[$term])) ? $terms[$term] : '('.$terms[$term].')';
|
||||||
|
|
||||||
if ($containsSpace) {
|
if ($containsSpace || is_numeric($terms[$term])) {
|
||||||
$recomposed .= '"';
|
$recomposed .= '"';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Templating\Entity;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implements ChillEntityRenderInterface<GenderIconEnum>
|
||||||
|
*/
|
||||||
|
final readonly class ChillGenderIconRender implements ChillEntityRenderInterface
|
||||||
|
{
|
||||||
|
public function renderBox($icon, array $options): string
|
||||||
|
{
|
||||||
|
return '<i class="'.htmlspecialchars($icon->value, ENT_QUOTES, 'UTF-8').'"></i>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderString($icon, array $options): string
|
||||||
|
{
|
||||||
|
return $icon->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supports($icon, array $options): bool
|
||||||
|
{
|
||||||
|
return $icon instanceof GenderIconEnum;
|
||||||
|
}
|
||||||
|
}
|
@ -49,6 +49,8 @@ services:
|
|||||||
|
|
||||||
Chill\MainBundle\Templating\Entity\NewsItemRender: ~
|
Chill\MainBundle\Templating\Entity\NewsItemRender: ~
|
||||||
|
|
||||||
|
Chill\MainBundle\Templating\Entity\ChillGenderIconRender: ~
|
||||||
|
|
||||||
Chill\MainBundle\Templating\Entity\UserRender: ~
|
Chill\MainBundle\Templating\Entity\UserRender: ~
|
||||||
|
|
||||||
Chill\MainBundle\Templating\Listing\:
|
Chill\MainBundle\Templating\Listing\:
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Main;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20240926093955 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Create gender table and default entities';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('CREATE SEQUENCE chill_main_gender_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||||
|
$this->addSql('CREATE TABLE chill_main_gender (id INT NOT NULL, label JSON NOT NULL, active BOOLEAN NOT NULL, genderTranslation VARCHAR(255) NOT NULL, icon VARCHAR(255) NOT NULL, ordering DOUBLE PRECISION DEFAULT \'0.0\', PRIMARY KEY(id))');
|
||||||
|
|
||||||
|
// Insert the four gender records into the chill_main_gender table
|
||||||
|
$this->addSql("
|
||||||
|
INSERT INTO chill_main_gender (id, label, active, genderTranslation, icon, ordering)
|
||||||
|
VALUES
|
||||||
|
(nextval('chill_main_gender_id_seq'),
|
||||||
|
'{\"fr\": \"homme\", \"nl\": \"man\"}',
|
||||||
|
true,
|
||||||
|
'man',
|
||||||
|
'',
|
||||||
|
1.0
|
||||||
|
),
|
||||||
|
(nextval('chill_main_gender_id_seq'),
|
||||||
|
'{\"fr\": \"femme\", \"nl\": \"vrouw\"}',
|
||||||
|
true,
|
||||||
|
'woman',
|
||||||
|
'',
|
||||||
|
1.1
|
||||||
|
),
|
||||||
|
(nextval('chill_main_gender_id_seq'),
|
||||||
|
'{\"fr\": \"neutre\", \"nl\": \"neutraal\"}',
|
||||||
|
true,
|
||||||
|
'neutral',
|
||||||
|
'',
|
||||||
|
1.1
|
||||||
|
),
|
||||||
|
(nextval('chill_main_gender_id_seq'),
|
||||||
|
'{\"fr\": \"inconnu\", \"nl\": \"ongekend\"}',
|
||||||
|
true,
|
||||||
|
'unknown',
|
||||||
|
'',
|
||||||
|
1.2
|
||||||
|
)
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('DROP SEQUENCE chill_main_gender_id_seq CASCADE');
|
||||||
|
$this->addSql('DROP TABLE chill_main_gender');
|
||||||
|
}
|
||||||
|
}
|
@ -43,6 +43,7 @@ lifecycleUpdate: Evenements de création et mise à jour
|
|||||||
address_fields: Données liées à l'adresse
|
address_fields: Données liées à l'adresse
|
||||||
Datas: Données
|
Datas: Données
|
||||||
No title: Aucun titre
|
No title: Aucun titre
|
||||||
|
icon: icône
|
||||||
|
|
||||||
user:
|
user:
|
||||||
profile:
|
profile:
|
||||||
@ -447,6 +448,12 @@ crud:
|
|||||||
title_delete: Supprimer une actualité
|
title_delete: Supprimer une actualité
|
||||||
button_delete: Supprimer
|
button_delete: Supprimer
|
||||||
confirm_message_delete: Êtes-vous sûr de vouloir supprimer l'actualité, "%as_string%" ?
|
confirm_message_delete: Êtes-vous sûr de vouloir supprimer l'actualité, "%as_string%" ?
|
||||||
|
main_gender:
|
||||||
|
index:
|
||||||
|
title: Liste des genres
|
||||||
|
add_new: Ajouter un genre
|
||||||
|
title_new: Nouveau genre
|
||||||
|
title_edit: Modifier un genre
|
||||||
|
|
||||||
No entities: Aucun élément
|
No entities: Aucun élément
|
||||||
|
|
||||||
@ -704,4 +711,8 @@ news:
|
|||||||
read_more: Lire la suite
|
read_more: Lire la suite
|
||||||
show_details: Voir l'actualité
|
show_details: Voir l'actualité
|
||||||
|
|
||||||
|
gender:
|
||||||
|
genderTranslation: traduction grammaticale
|
||||||
|
not defined: Non défini
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,11 +15,14 @@ use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
|
|||||||
use Chill\MainBundle\Entity\Address;
|
use Chill\MainBundle\Entity\Address;
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Entity\Country;
|
use Chill\MainBundle\Entity\Country;
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Entity\GenderEnum;
|
||||||
use Chill\MainBundle\Entity\PostalCode;
|
use Chill\MainBundle\Entity\PostalCode;
|
||||||
use Chill\MainBundle\Entity\Scope;
|
use Chill\MainBundle\Entity\Scope;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Repository\CenterRepository;
|
use Chill\MainBundle\Repository\CenterRepository;
|
||||||
use Chill\MainBundle\Repository\CountryRepository;
|
use Chill\MainBundle\Repository\CountryRepository;
|
||||||
|
use Chill\MainBundle\Repository\GenderRepository;
|
||||||
use Chill\MainBundle\Repository\ScopeRepository;
|
use Chill\MainBundle\Repository\ScopeRepository;
|
||||||
use Chill\MainBundle\Repository\UserRepository;
|
use Chill\MainBundle\Repository\UserRepository;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
@ -77,12 +80,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
|||||||
*/
|
*/
|
||||||
protected array $cacheUsers = [];
|
protected array $cacheUsers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array|Gender[]
|
||||||
|
*/
|
||||||
|
protected array $cacheGenders = [];
|
||||||
|
|
||||||
protected Generator $faker;
|
protected Generator $faker;
|
||||||
|
|
||||||
protected NativeLoader $loader;
|
protected NativeLoader $loader;
|
||||||
|
|
||||||
private array $genders = [Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER];
|
|
||||||
|
|
||||||
private array $peoples = [
|
private array $peoples = [
|
||||||
[
|
[
|
||||||
'lastName' => 'Depardieu',
|
'lastName' => 'Depardieu',
|
||||||
@ -90,7 +96,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
|||||||
'birthdate' => '1948-12-27',
|
'birthdate' => '1948-12-27',
|
||||||
'placeOfBirth' => 'Châteauroux',
|
'placeOfBirth' => 'Châteauroux',
|
||||||
'nationality' => 'RU',
|
'nationality' => 'RU',
|
||||||
'gender' => Person::MALE_GENDER,
|
'gender' => GenderEnum::MALE,
|
||||||
'center' => 'Center A',
|
'center' => 'Center A',
|
||||||
'accompanyingPeriods' => [
|
'accompanyingPeriods' => [
|
||||||
[
|
[
|
||||||
@ -119,7 +125,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
|||||||
'maritalStatus' => 'ms_divorce',
|
'maritalStatus' => 'ms_divorce',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
// to have a person with same birthdate of Gérard Depardieu
|
// to have a person with same birthdate as Gérard Depardieu
|
||||||
'lastName' => 'Van Snick',
|
'lastName' => 'Van Snick',
|
||||||
'firstName' => 'Bart',
|
'firstName' => 'Bart',
|
||||||
'birthdate' => '1948-12-27',
|
'birthdate' => '1948-12-27',
|
||||||
@ -131,7 +137,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
|||||||
'lastName' => 'Depardieu',
|
'lastName' => 'Depardieu',
|
||||||
'firstName' => 'Charline',
|
'firstName' => 'Charline',
|
||||||
'birthdate' => '1970-10-15',
|
'birthdate' => '1970-10-15',
|
||||||
'gender' => Person::FEMALE_GENDER,
|
'gender' => GenderEnum::FEMALE,
|
||||||
'center' => 'Center A',
|
'center' => 'Center A',
|
||||||
'maritalStatus' => 'ms_legalco',
|
'maritalStatus' => 'ms_legalco',
|
||||||
],
|
],
|
||||||
@ -228,6 +234,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
|||||||
protected MaritalStatusRepository $maritalStatusRepository,
|
protected MaritalStatusRepository $maritalStatusRepository,
|
||||||
protected ScopeRepository $scopeRepository,
|
protected ScopeRepository $scopeRepository,
|
||||||
protected UserRepository $userRepository,
|
protected UserRepository $userRepository,
|
||||||
|
protected GenderRepository $genderRepository,
|
||||||
) {
|
) {
|
||||||
$this->faker = Factory::create('fr_FR');
|
$this->faker = Factory::create('fr_FR');
|
||||||
$this->faker->addProvider($this);
|
$this->faker->addProvider($this);
|
||||||
@ -272,9 +279,17 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord
|
|||||||
/**
|
/**
|
||||||
* @internal This method is public and called by faker as a custom generator
|
* @internal This method is public and called by faker as a custom generator
|
||||||
*/
|
*/
|
||||||
public function getRandomGender(): string
|
public function getRandomGender(int $nullPercentage = 50): ?Gender
|
||||||
{
|
{
|
||||||
return $this->genders[array_rand($this->genders)];
|
if (0 === \count($this->cacheGenders)) {
|
||||||
|
$this->cacheGenders = $this->genderRepository->findByActiveOrdered();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\random_int(0, 100) > $nullPercentage) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->cacheGenders[array_rand($this->cacheGenders)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +21,7 @@ use Chill\MainBundle\Entity\Center;
|
|||||||
use Chill\MainBundle\Entity\Civility;
|
use Chill\MainBundle\Entity\Civility;
|
||||||
use Chill\MainBundle\Entity\Country;
|
use Chill\MainBundle\Entity\Country;
|
||||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||||
use Chill\MainBundle\Entity\Language;
|
use Chill\MainBundle\Entity\Language;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
@ -59,19 +60,11 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
|||||||
#[HouseholdMembershipSequential(groups: ['household_memberships'])]
|
#[HouseholdMembershipSequential(groups: ['household_memberships'])]
|
||||||
class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateInterface, \Stringable
|
class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateInterface, \Stringable
|
||||||
{
|
{
|
||||||
final public const BOTH_GENDER = 'both';
|
|
||||||
|
|
||||||
// have days in commun
|
// have days in commun
|
||||||
final public const ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD = 2; // where there exist
|
final public const ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD = 2; // where there exist
|
||||||
|
|
||||||
final public const ERROR_PERIODS_ARE_COLLAPSING = 1; // when two different periods
|
final public const ERROR_PERIODS_ARE_COLLAPSING = 1; // when two different periods
|
||||||
|
|
||||||
final public const FEMALE_GENDER = 'woman';
|
|
||||||
|
|
||||||
final public const MALE_GENDER = 'man';
|
|
||||||
|
|
||||||
final public const NO_INFORMATION = 'unknown';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accept receiving email.
|
* Accept receiving email.
|
||||||
*/
|
*/
|
||||||
@ -242,11 +235,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
private ?string $fullnameCanonical = '';
|
private ?string $fullnameCanonical = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The person's gender.
|
* NEW column : The person's gender.
|
||||||
*/
|
*/
|
||||||
#[Assert\NotNull(message: 'The gender must be set')]
|
#[Assert\NotNull(message: 'The gender must be set')]
|
||||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 9, nullable: true)]
|
#[ORM\ManyToOne(targetEntity: Gender::class)]
|
||||||
private ?string $gender = null;
|
private ?Gender $gender = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comment on gender.
|
* Comment on gender.
|
||||||
@ -1003,7 +996,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
return $this->fullnameCanonical;
|
return $this->fullnameCanonical;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGender(): ?string
|
public function getGender(): ?Gender
|
||||||
{
|
{
|
||||||
return $this->gender;
|
return $this->gender;
|
||||||
}
|
}
|
||||||
@ -1013,24 +1006,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
return $this->genderComment;
|
return $this->genderComment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* return gender as a Numeric form.
|
|
||||||
* This is used for translations.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*
|
|
||||||
* @deprecated Keep for legacy. Used in Chill 1.5 for feminize before icu translations
|
|
||||||
*/
|
|
||||||
public function getGenderNumeric()
|
|
||||||
{
|
|
||||||
return match ($this->getGender()) {
|
|
||||||
self::FEMALE_GENDER => 1,
|
|
||||||
self::MALE_GENDER => 0,
|
|
||||||
self::BOTH_GENDER => 2,
|
|
||||||
default => -1,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHouseholdAddresses(): Collection
|
public function getHouseholdAddresses(): Collection
|
||||||
{
|
{
|
||||||
return $this->householdAddresses;
|
return $this->householdAddresses;
|
||||||
@ -1532,7 +1507,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setGender(?string $gender): self
|
public function setGender(?Gender $gender): self
|
||||||
{
|
{
|
||||||
$this->gender = $gender;
|
$this->gender = $gender;
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
|
namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators;
|
||||||
|
|
||||||
use Chill\MainBundle\Export\AggregatorInterface;
|
use Chill\MainBundle\Export\AggregatorInterface;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\MainBundle\Repository\GenderRepository;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
@ -20,7 +21,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
|
|
||||||
final readonly class GenderAggregator implements AggregatorInterface
|
final readonly class GenderAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
public function __construct(private TranslatorInterface $translator) {}
|
public function __construct(private TranslatorInterface $translator, private TranslatableStringHelperInterface $translatableStringHelper, private GenderRepository $repository) {}
|
||||||
|
|
||||||
public function addRole(): ?string
|
public function addRole(): ?string
|
||||||
{
|
{
|
||||||
@ -29,7 +30,8 @@ final readonly class GenderAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$qb->addSelect('person.gender as gender');
|
$qb->leftJoin('person.gender', 'g');
|
||||||
|
$qb->addSelect('g.id as gender');
|
||||||
|
|
||||||
$qb->addGroupBy('gender');
|
$qb->addGroupBy('gender');
|
||||||
}
|
}
|
||||||
@ -48,30 +50,20 @@ final readonly class GenderAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
public function getLabels($key, array $values, $data)
|
public function getLabels($key, array $values, $data)
|
||||||
{
|
{
|
||||||
return function ($value) {
|
return function (int|string|null $value) {
|
||||||
switch ($value) {
|
if (null === $value || '' === $value) {
|
||||||
case Person::FEMALE_GENDER:
|
return '';
|
||||||
return $this->translator->trans('woman');
|
|
||||||
|
|
||||||
case Person::MALE_GENDER:
|
|
||||||
return $this->translator->trans('man');
|
|
||||||
|
|
||||||
case Person::BOTH_GENDER:
|
|
||||||
return $this->translator->trans('both');
|
|
||||||
|
|
||||||
case Person::NO_INFORMATION:
|
|
||||||
return $this->translator->trans('unknown');
|
|
||||||
|
|
||||||
case null:
|
|
||||||
case '':
|
|
||||||
return $this->translator->trans('Not given');
|
|
||||||
|
|
||||||
case '_header':
|
|
||||||
return $this->translator->trans('Gender');
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new \LogicException(sprintf('The value %s is not valid', $value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('_header' === $value) {
|
||||||
|
return $this->translator->trans('Gender');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $gender = $this->repository->find((int) $value)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) $this->translatableStringHelper->localize($gender->getLabel());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Export\Filter\PersonFilters;
|
namespace Chill\PersonBundle\Export\Filter\PersonFilters;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Export\DataTransformerInterface;
|
||||||
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
||||||
use Chill\MainBundle\Export\FilterInterface;
|
use Chill\MainBundle\Export\FilterInterface;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\MainBundle\Repository\GenderRepository;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Doctrine\ORM\Query\Expr;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
@ -24,17 +26,15 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
|
|
||||||
class GenderFilter implements
|
class GenderFilter implements
|
||||||
ExportElementValidatedInterface,
|
ExportElementValidatedInterface,
|
||||||
FilterInterface
|
FilterInterface,
|
||||||
|
DataTransformerInterface
|
||||||
{
|
{
|
||||||
/**
|
// inject gender repository and find the active genders so that you can pass them to the ChoiceType (ordered by ordering)
|
||||||
* @var TranslatorInterface
|
public function __construct(
|
||||||
*/
|
private readonly TranslatorInterface $translator,
|
||||||
protected $translator;
|
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||||
|
private readonly GenderRepository $genderRepository,
|
||||||
public function __construct(TranslatorInterface $translator)
|
) {}
|
||||||
{
|
|
||||||
$this->translator = $translator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addRole(): ?string
|
public function addRole(): ?string
|
||||||
{
|
{
|
||||||
@ -46,23 +46,17 @@ class GenderFilter implements
|
|||||||
$where = $qb->getDQLPart('where');
|
$where = $qb->getDQLPart('where');
|
||||||
$isIn = $qb->expr()->in('person.gender', ':person_gender');
|
$isIn = $qb->expr()->in('person.gender', ':person_gender');
|
||||||
|
|
||||||
if (!\in_array('null', $data['accepted_genders'], true)) {
|
$acceptedGenders = $data['accepted_genders_entity'];
|
||||||
|
$nullIncluded = in_array(null, $acceptedGenders ?? [], true);
|
||||||
|
|
||||||
|
if (!$nullIncluded) {
|
||||||
$clause = $isIn;
|
$clause = $isIn;
|
||||||
} else {
|
} else {
|
||||||
$clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender'));
|
$clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($where instanceof Expr\Andx) {
|
$qb->andWhere($clause);
|
||||||
$where->add($clause);
|
$qb->setParameter('person_gender', array_filter($acceptedGenders ?? [], fn ($gender) => null !== $gender));
|
||||||
} else {
|
|
||||||
$where = $qb->expr()->andX($clause);
|
|
||||||
}
|
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
$qb->setParameter('person_gender', \array_filter(
|
|
||||||
$data['accepted_genders'],
|
|
||||||
static fn ($el) => 'null' !== $el
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn()
|
public function applyOn()
|
||||||
@ -72,19 +66,42 @@ class GenderFilter implements
|
|||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
$builder->add('accepted_genders', ChoiceType::class, [
|
$genderChoices = $this->genderRepository->findByActiveOrdered();
|
||||||
'choices' => [
|
$choices = ['None' => null];
|
||||||
'Woman' => Person::FEMALE_GENDER,
|
|
||||||
'Man' => Person::MALE_GENDER,
|
foreach ($genderChoices as $gender) {
|
||||||
'Both' => Person::BOTH_GENDER,
|
$choices[$this->translatableStringHelper->localize($gender->getLabel())] = $gender->getId();
|
||||||
'Unknown' => Person::NO_INFORMATION,
|
}
|
||||||
'Not given' => 'null',
|
|
||||||
],
|
$builder->add('accepted_genders_entity', ChoiceType::class, [
|
||||||
|
'choices' => $choices,
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'expanded' => true,
|
'expanded' => true,
|
||||||
|
'placeholder' => 'Select gender',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function transformData(?array $before): array
|
||||||
|
{
|
||||||
|
$transformedData = [];
|
||||||
|
$transformedData['accepted_genders_entity'] = $before['accepted_genders_entity'] ?? [];
|
||||||
|
|
||||||
|
if (array_key_exists('accepted_genders', $before)) {
|
||||||
|
foreach ($before['accepted_genders'] as $genderBefore) {
|
||||||
|
foreach ($this->genderRepository->findByGenderTranslation(
|
||||||
|
match ($genderBefore) {
|
||||||
|
'both' => 'neutral',
|
||||||
|
default => $genderBefore,
|
||||||
|
}
|
||||||
|
) as $gender) {
|
||||||
|
$transformedData['accepted_genders_entity'][] = $gender;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $transformedData;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFormDefaultData(): array
|
public function getFormDefaultData(): array
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
@ -94,11 +111,11 @@ class GenderFilter implements
|
|||||||
{
|
{
|
||||||
$genders = [];
|
$genders = [];
|
||||||
|
|
||||||
foreach ($data['accepted_genders'] as $g) {
|
foreach ($data['accepted_genders_entity'] as $g) {
|
||||||
if ('null' === $g) {
|
if (null === $g) {
|
||||||
$genders[] = $this->translator->trans('Not given');
|
$genders[] = $this->translator->trans('export.filter.person.gender.no_gender');
|
||||||
} else {
|
} else {
|
||||||
$genders[] = $this->translator->trans($g);
|
$genders[] = $this->translatableStringHelper->localize($this->genderRepository->find($g)->getLabel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +137,7 @@ class GenderFilter implements
|
|||||||
|
|
||||||
public function validateForm($data, ExecutionContextInterface $context)
|
public function validateForm($data, ExecutionContextInterface $context)
|
||||||
{
|
{
|
||||||
if (!\is_array($data['accepted_genders']) || 0 === \count($data['accepted_genders'])) {
|
if (!\is_iterable($data['accepted_genders_entity']) || 0 === \count($data['accepted_genders_entity'])) {
|
||||||
$context->buildViolation('You should select an option')
|
$context->buildViolation('You should select an option')
|
||||||
->addViolation();
|
->addViolation();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ use Chill\MainBundle\Export\Helper\ExportAddressHelper;
|
|||||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
||||||
use Chill\MainBundle\Repository\CivilityRepositoryInterface;
|
use Chill\MainBundle\Repository\CivilityRepositoryInterface;
|
||||||
use Chill\MainBundle\Repository\CountryRepository;
|
use Chill\MainBundle\Repository\CountryRepository;
|
||||||
|
use Chill\MainBundle\Repository\GenderRepository;
|
||||||
use Chill\MainBundle\Repository\LanguageRepositoryInterface;
|
use Chill\MainBundle\Repository\LanguageRepositoryInterface;
|
||||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
@ -80,6 +81,7 @@ final readonly class ListPersonHelper
|
|||||||
private TranslatableStringHelper $translatableStringHelper,
|
private TranslatableStringHelper $translatableStringHelper,
|
||||||
private TranslatorInterface $translator,
|
private TranslatorInterface $translator,
|
||||||
private UserRepositoryInterface $userRepository,
|
private UserRepositoryInterface $userRepository,
|
||||||
|
private GenderRepository $genderRepository,
|
||||||
/**
|
/**
|
||||||
* @var iterable<CustomizeListPersonHelperInterface>
|
* @var iterable<CustomizeListPersonHelperInterface>
|
||||||
*/
|
*/
|
||||||
@ -173,6 +175,11 @@ final readonly class ListPersonHelper
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'gender':
|
||||||
|
$qb->addSelect('IDENTITY(person.gender) AS gender');
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case 'maritalStatus':
|
case 'maritalStatus':
|
||||||
$qb->addSelect('IDENTITY(person.maritalStatus) AS maritalStatus');
|
$qb->addSelect('IDENTITY(person.maritalStatus) AS maritalStatus');
|
||||||
|
|
||||||
@ -325,7 +332,13 @@ final readonly class ListPersonHelper
|
|||||||
return $this->translator->trans($key);
|
return $this->translator->trans($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->translator->trans($value);
|
if (null === $value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$gender = $this->genderRepository->find($value);
|
||||||
|
|
||||||
|
return $this->translatableStringHelper->localize($gender->getLabel());
|
||||||
};
|
};
|
||||||
|
|
||||||
case 'maritalStatus':
|
case 'maritalStatus':
|
||||||
|
@ -20,8 +20,8 @@ use Chill\MainBundle\Form\Type\PickCenterType;
|
|||||||
use Chill\MainBundle\Form\Type\PickCivilityType;
|
use Chill\MainBundle\Form\Type\PickCivilityType;
|
||||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Form\Type\GenderType;
|
|
||||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickGenderType;
|
||||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||||
use libphonenumber\PhoneNumberType;
|
use libphonenumber\PhoneNumberType;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
@ -60,7 +60,7 @@ final class CreationPersonType extends AbstractType
|
|||||||
'label' => 'Civility',
|
'label' => 'Civility',
|
||||||
'placeholder' => 'choose civility',
|
'placeholder' => 'choose civility',
|
||||||
])
|
])
|
||||||
->add('gender', GenderType::class, [
|
->add('gender', PickGenderType::class, [
|
||||||
'required' => true, 'placeholder' => null,
|
'required' => true, 'placeholder' => null,
|
||||||
])
|
])
|
||||||
->add('birthdate', ChillDateType::class, [
|
->add('birthdate', ChillDateType::class, [
|
||||||
|
@ -24,9 +24,9 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
|||||||
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Entity\PersonPhone;
|
use Chill\PersonBundle\Entity\PersonPhone;
|
||||||
use Chill\PersonBundle\Form\Type\GenderType;
|
|
||||||
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
use Chill\PersonBundle\Form\Type\PersonAltNameType;
|
||||||
use Chill\PersonBundle\Form\Type\PersonPhoneType;
|
use Chill\PersonBundle\Form\Type\PersonPhoneType;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickGenderType;
|
||||||
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
use Chill\PersonBundle\Form\Type\Select2MaritalStatusType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\CallbackTransformer;
|
use Symfony\Component\Form\CallbackTransformer;
|
||||||
@ -80,7 +80,7 @@ class PersonType extends AbstractType
|
|||||||
'input' => 'datetime_immutable',
|
'input' => 'datetime_immutable',
|
||||||
'widget' => 'single_text',
|
'widget' => 'single_text',
|
||||||
])
|
])
|
||||||
->add('gender', GenderType::class, [
|
->add('gender', PickGenderType::class, [
|
||||||
'required' => true,
|
'required' => true,
|
||||||
])
|
])
|
||||||
->add('genderComment', CommentType::class, [
|
->add('genderComment', CommentType::class, [
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chill is a software for social workers
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view
|
|
||||||
* the LICENSE file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Chill\PersonBundle\Form\Type;
|
|
||||||
|
|
||||||
use Chill\PersonBundle\Entity\Person;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A type to select the civil union state.
|
|
||||||
*/
|
|
||||||
class GenderType extends AbstractType
|
|
||||||
{
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
|
||||||
{
|
|
||||||
$a = [
|
|
||||||
Person::MALE_GENDER => Person::MALE_GENDER,
|
|
||||||
Person::FEMALE_GENDER => Person::FEMALE_GENDER,
|
|
||||||
Person::BOTH_GENDER => Person::BOTH_GENDER,
|
|
||||||
];
|
|
||||||
|
|
||||||
$resolver->setDefaults([
|
|
||||||
'choices' => $a,
|
|
||||||
'expanded' => true,
|
|
||||||
'multiple' => false,
|
|
||||||
'placeholder' => null,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getParent()
|
|
||||||
{
|
|
||||||
return ChoiceType::class;
|
|
||||||
}
|
|
||||||
}
|
|
51
src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php
Normal file
51
src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Form\Type;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\ORM\QueryBuilder;
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type to select the civil union state.
|
||||||
|
*/
|
||||||
|
class PickGenderType extends AbstractType
|
||||||
|
{
|
||||||
|
public function __construct(private readonly TranslatableStringHelper $translatableStringHelper) {}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefault('label', 'Gender')
|
||||||
|
->setDefault(
|
||||||
|
'choice_label',
|
||||||
|
fn (Gender $gender): string => $this->translatableStringHelper->localize($gender->getLabel())
|
||||||
|
)
|
||||||
|
->setDefault(
|
||||||
|
'query_builder',
|
||||||
|
static fn (EntityRepository $er): QueryBuilder => $er->createQueryBuilder('g')
|
||||||
|
->where('g.active = true')
|
||||||
|
->orderBy('g.order'),
|
||||||
|
)
|
||||||
|
->setDefault('placeholder', 'choose gender')
|
||||||
|
->setDefault('class', Gender::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return EntityType::class;
|
||||||
|
}
|
||||||
|
}
|
@ -45,13 +45,17 @@ class AdminPersonMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'route' => 'chill_crud_main_civility_index',
|
'route' => 'chill_crud_main_civility_index',
|
||||||
])->setExtras(['order' => 2010]);
|
])->setExtras(['order' => 2010]);
|
||||||
|
|
||||||
|
$menu->addChild('Gender', [
|
||||||
|
'route' => 'chill_crud_main_gender_index',
|
||||||
|
])->setExtras(['order' => 2020]);
|
||||||
|
|
||||||
$menu->addChild('Marital status', [
|
$menu->addChild('Marital status', [
|
||||||
'route' => 'chill_crud_person_marital-status_index',
|
'route' => 'chill_crud_person_marital-status_index',
|
||||||
])->setExtras(['order' => 2020]);
|
])->setExtras(['order' => 2030]);
|
||||||
|
|
||||||
$menu->addChild('person_admin.person_resource_kind', [
|
$menu->addChild('person_admin.person_resource_kind', [
|
||||||
'route' => 'chill_crud_person_resource-kind_index',
|
'route' => 'chill_crud_person_resource-kind_index',
|
||||||
])->setExtras(['order' => 2030]);
|
])->setExtras(['order' => 2040]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getMenuIds(): array
|
public static function getMenuIds(): array
|
||||||
|
@ -34,7 +34,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
|||||||
?\DateTimeInterface $birthdate = null,
|
?\DateTimeInterface $birthdate = null,
|
||||||
?\DateTimeInterface $birthdateBefore = null,
|
?\DateTimeInterface $birthdateBefore = null,
|
||||||
?\DateTimeInterface $birthdateAfter = null,
|
?\DateTimeInterface $birthdateAfter = null,
|
||||||
?string $gender = null,
|
?int $gender = null,
|
||||||
?string $countryCode = null,
|
?string $countryCode = null,
|
||||||
?string $phonenumber = null,
|
?string $phonenumber = null,
|
||||||
?string $city = null,
|
?string $city = null,
|
||||||
@ -62,7 +62,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
|||||||
?\DateTimeInterface $birthdate = null,
|
?\DateTimeInterface $birthdate = null,
|
||||||
?\DateTimeInterface $birthdateBefore = null,
|
?\DateTimeInterface $birthdateBefore = null,
|
||||||
?\DateTimeInterface $birthdateAfter = null,
|
?\DateTimeInterface $birthdateAfter = null,
|
||||||
?string $gender = null,
|
?int $gender = null,
|
||||||
?string $countryCode = null,
|
?string $countryCode = null,
|
||||||
?string $phonenumber = null,
|
?string $phonenumber = null,
|
||||||
?string $city = null,
|
?string $city = null,
|
||||||
@ -96,7 +96,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
|||||||
?\DateTimeInterface $birthdate = null,
|
?\DateTimeInterface $birthdate = null,
|
||||||
?\DateTimeInterface $birthdateBefore = null,
|
?\DateTimeInterface $birthdateBefore = null,
|
||||||
?\DateTimeInterface $birthdateAfter = null,
|
?\DateTimeInterface $birthdateAfter = null,
|
||||||
?string $gender = null,
|
?int $gender = null,
|
||||||
?string $countryCode = null,
|
?string $countryCode = null,
|
||||||
?string $phonenumber = null,
|
?string $phonenumber = null,
|
||||||
?string $city = null,
|
?string $city = null,
|
||||||
@ -202,7 +202,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $gender) {
|
if (null !== $gender) {
|
||||||
$query->andWhereClause('person.gender = ?', [$gender]);
|
$query->andWhereClause('person.gender_id = ?', [$gender]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
@ -253,7 +253,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor
|
|||||||
?\DateTimeInterface $birthdate = null,
|
?\DateTimeInterface $birthdate = null,
|
||||||
?\DateTimeInterface $birthdateBefore = null,
|
?\DateTimeInterface $birthdateBefore = null,
|
||||||
?\DateTimeInterface $birthdateAfter = null,
|
?\DateTimeInterface $birthdateAfter = null,
|
||||||
?string $gender = null,
|
?int $gender = null,
|
||||||
?string $countryCode = null,
|
?string $countryCode = null,
|
||||||
?string $phonenumber = null,
|
?string $phonenumber = null,
|
||||||
?string $city = null,
|
?string $city = null,
|
||||||
|
@ -23,7 +23,7 @@ interface PersonACLAwareRepositoryInterface
|
|||||||
?\DateTimeInterface $birthdate = null,
|
?\DateTimeInterface $birthdate = null,
|
||||||
?\DateTimeInterface $birthdateBefore = null,
|
?\DateTimeInterface $birthdateBefore = null,
|
||||||
?\DateTimeInterface $birthdateAfter = null,
|
?\DateTimeInterface $birthdateAfter = null,
|
||||||
?string $gender = null,
|
?int $gender = null,
|
||||||
?string $countryCode = null,
|
?string $countryCode = null,
|
||||||
?string $phonenumber = null,
|
?string $phonenumber = null,
|
||||||
?string $city = null,
|
?string $city = null,
|
||||||
@ -36,7 +36,7 @@ interface PersonACLAwareRepositoryInterface
|
|||||||
?\DateTimeInterface $birthdate = null,
|
?\DateTimeInterface $birthdate = null,
|
||||||
?\DateTimeInterface $birthdateBefore = null,
|
?\DateTimeInterface $birthdateBefore = null,
|
||||||
?\DateTimeInterface $birthdateAfter = null,
|
?\DateTimeInterface $birthdateAfter = null,
|
||||||
?string $gender = null,
|
?int $gender = null,
|
||||||
?string $countryCode = null,
|
?string $countryCode = null,
|
||||||
?string $phonenumber = null,
|
?string $phonenumber = null,
|
||||||
?string $city = null,
|
?string $city = null,
|
||||||
@ -55,7 +55,7 @@ interface PersonACLAwareRepositoryInterface
|
|||||||
?\DateTimeInterface $birthdate = null,
|
?\DateTimeInterface $birthdate = null,
|
||||||
?\DateTimeInterface $birthdateBefore = null,
|
?\DateTimeInterface $birthdateBefore = null,
|
||||||
?\DateTimeInterface $birthdateAfter = null,
|
?\DateTimeInterface $birthdateAfter = null,
|
||||||
?string $gender = null,
|
?int $gender = null,
|
||||||
?string $countryCode = null,
|
?string $countryCode = null,
|
||||||
?string $phonenumber = null,
|
?string $phonenumber = null,
|
||||||
?string $city = null,
|
?string $city = null,
|
||||||
|
@ -128,7 +128,7 @@ export default {
|
|||||||
body.mobilenumber = payload.data.mobilenumber;
|
body.mobilenumber = payload.data.mobilenumber;
|
||||||
body.email = payload.data.email;
|
body.email = payload.data.email;
|
||||||
body.altNames = payload.data.altNames;
|
body.altNames = payload.data.altNames;
|
||||||
body.gender = payload.data.gender;
|
body.gender = {id: payload.data.gender.id, type: payload.data.gender.type };
|
||||||
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type }; }
|
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type }; }
|
||||||
|
|
||||||
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
||||||
|
@ -153,7 +153,7 @@ export default {
|
|||||||
body.mobilenumber = payload.data.mobilenumber;
|
body.mobilenumber = payload.data.mobilenumber;
|
||||||
body.email = payload.data.email;
|
body.email = payload.data.email;
|
||||||
body.altNames = payload.data.altNames;
|
body.altNames = payload.data.altNames;
|
||||||
body.gender = payload.data.gender;
|
body.gender = {id: payload.data.gender.id, type: payload.data.gender.type };
|
||||||
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type}; }
|
if (payload.data.civility !== null) { body.civility = {id: payload.data.civility.id, type: payload.data.civility.type}; }
|
||||||
|
|
||||||
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
{{ $t('household_members_editor.holder') }}
|
{{ $t('household_members_editor.holder') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="conc.person.birthdate !== null">{{ $t('person.born', {'gender': conc.person.gender} ) }}</div>
|
<div v-if="conc.person.birthdate !== null">{{ $t('person.born', {'gender': conc.person.gender.genderTranslation} ) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-col">
|
<div class="item-col">
|
||||||
<ul class="list-content fa-ul">
|
<ul class="list-content fa-ul">
|
||||||
|
@ -12,10 +12,6 @@ const visMessages = {
|
|||||||
Holder: 'Titulaire',
|
Holder: 'Titulaire',
|
||||||
Legend: 'Calques',
|
Legend: 'Calques',
|
||||||
concerned: 'concerné',
|
concerned: 'concerné',
|
||||||
// both: 'neutre, non binaire',
|
|
||||||
woman: 'féminin',
|
|
||||||
man: 'masculin',
|
|
||||||
undefined: "genre non précisé",
|
|
||||||
years: 'ans',
|
years: 'ans',
|
||||||
click_to_expand: 'cliquez pour étendre',
|
click_to_expand: 'cliquez pour étendre',
|
||||||
add_relationship_link: "Créer un lien de filiation",
|
add_relationship_link: "Créer un lien de filiation",
|
||||||
@ -64,7 +60,7 @@ const visMessages = {
|
|||||||
placeholder: "Choisissez le genre de l'usager",
|
placeholder: "Choisissez le genre de l'usager",
|
||||||
woman: "Féminin",
|
woman: "Féminin",
|
||||||
man: "Masculin",
|
man: "Masculin",
|
||||||
both: "Neutre, non binaire",
|
neutral: "Neutre, non binaire",
|
||||||
undefined: "Non renseigné",
|
undefined: "Non renseigné",
|
||||||
unknown: "Non renseigné"
|
unknown: "Non renseigné"
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createStore } from 'vuex'
|
import { createStore } from 'vuex'
|
||||||
import { getHouseholdByPerson, getCoursesByPerson, getRelationshipsByPerson } from './api'
|
import { getHouseholdByPerson, getCoursesByPerson, getRelationshipsByPerson } from './api'
|
||||||
import { getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, getRelationshipDirection, splitId, getGender, getAge } from './vis-network'
|
import { getHouseholdLabel, getHouseholdWidth, getRelationshipLabel, getRelationshipTitle, getRelationshipDirection, splitId, getAge } from './vis-network'
|
||||||
import {visMessages} from "./i18n";
|
import {visMessages} from "./i18n";
|
||||||
import { darkBlue, darkBrown, darkGreen, lightBlue, lightBrown, lightGreen } from './colors';
|
import { darkBlue, darkBrown, darkGreen, lightBlue, lightBrown, lightGreen } from './colors';
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ const store = createStore({
|
|||||||
person.group = person.type
|
person.group = person.type
|
||||||
person._id = person.id
|
person._id = person.id
|
||||||
person.id = `person_${person.id}`
|
person.id = `person_${person.id}`
|
||||||
person.label = `*${person.text}${person.deathdate ? ' (‡)' : ''}*\n_${getGender(person.gender)}${age}_${debug}`
|
person.label = `*${person.text}${person.deathdate ? ' (‡)' : ''}*\n_${person.gender.label.fr}${age}_${debug}`
|
||||||
person.folded = false
|
person.folded = false
|
||||||
// folded is used for missing persons
|
// folded is used for missing persons
|
||||||
if (options.folded) {
|
if (options.folded) {
|
||||||
|
@ -141,25 +141,6 @@ window.options = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param gender
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
const getGender = (gender) => {
|
|
||||||
switch (gender) {
|
|
||||||
case 'both':
|
|
||||||
return visMessages.fr.visgraph.both
|
|
||||||
case 'woman':
|
|
||||||
return visMessages.fr.visgraph.woman
|
|
||||||
case 'man':
|
|
||||||
return visMessages.fr.visgraph.man
|
|
||||||
case 'unknown':
|
|
||||||
return visMessages.fr.visgraph.unknown
|
|
||||||
default:
|
|
||||||
return visMessages.fr.visgraph.undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO only one abstract function (-> getAge() is repeated in PersonRenderBox.vue)
|
* TODO only one abstract function (-> getAge() is repeated in PersonRenderBox.vue)
|
||||||
* @param person
|
* @param person
|
||||||
@ -251,7 +232,6 @@ const splitId = (id, position) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getGender,
|
|
||||||
getAge,
|
getAge,
|
||||||
getHouseholdLabel,
|
getHouseholdLabel,
|
||||||
getHouseholdWidth,
|
getHouseholdWidth,
|
||||||
|
@ -24,6 +24,13 @@ const getCivilities = () =>
|
|||||||
throw Error('Error with request resource response');
|
throw Error('Error with request resource response');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getGenders = () => makeFetch("GET", '/api/1.0/main/gender.json')
|
||||||
|
// .then(response => {
|
||||||
|
// console.log(response)
|
||||||
|
// if (response.ok) { return response.json(); }
|
||||||
|
// throw Error('Error with request resource response');
|
||||||
|
// });
|
||||||
|
|
||||||
const getCentersForPersonCreation = () => makeFetch('GET', '/api/1.0/person/creation/authorized-centers', null);
|
const getCentersForPersonCreation = () => makeFetch('GET', '/api/1.0/person/creation/authorized-centers', null);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -67,6 +74,7 @@ export {
|
|||||||
getPerson,
|
getPerson,
|
||||||
getPersonAltNames,
|
getPersonAltNames,
|
||||||
getCivilities,
|
getCivilities,
|
||||||
|
getGenders,
|
||||||
postPerson,
|
postPerson,
|
||||||
patchPerson
|
patchPerson
|
||||||
};
|
};
|
||||||
|
@ -37,10 +37,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p v-if="options.addInfo === true" class="moreinfo">
|
<p v-if="options.addInfo === true" class="moreinfo">
|
||||||
<i :class="'fa fa-fw ' + getGenderIcon" :title="$t(getGender)"></i>
|
<gender-icon-render-box v-if="person.gender" :gender="person.gender"></gender-icon-render-box>
|
||||||
|
|
||||||
<time v-if="person.birthdate && !person.deathdate" :datetime="person.birthdate" :title="birthdate">
|
<time v-if="person.birthdate && !person.deathdate" :datetime="person.birthdate" :title="birthdate">
|
||||||
{{ $t(getGenderTranslation) + ' ' + $d(birthdate, 'text') }}
|
{{ $t(person.gender ? `renderbox.birthday.${person.gender.genderTranslation}` : 'renderbox.birthday.neutral') + ' ' + $d(birthdate, 'text') }}
|
||||||
</time>
|
</time>
|
||||||
|
|
||||||
<time v-else-if="person.birthdate && person.deathdate" :datetime="person.deathdate"
|
<time v-else-if="person.birthdate && person.deathdate" :datetime="person.deathdate"
|
||||||
@ -180,6 +179,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import {dateToISO, ISOToDate} from 'ChillMainAssets/chill/js/date';
|
import {dateToISO, ISOToDate} from 'ChillMainAssets/chill/js/date';
|
||||||
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue';
|
||||||
|
import GenderIconRenderBox from 'ChillMainAssets/vuejs/_components/Entity/GenderIconRenderBox.vue'
|
||||||
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
import Confidential from 'ChillMainAssets/vuejs/_components/Confidential.vue';
|
||||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue';
|
||||||
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue';
|
||||||
@ -190,6 +190,7 @@ export default {
|
|||||||
name: "PersonRenderBox",
|
name: "PersonRenderBox",
|
||||||
components: {
|
components: {
|
||||||
AddressRenderBox,
|
AddressRenderBox,
|
||||||
|
GenderIconRenderBox,
|
||||||
Confidential,
|
Confidential,
|
||||||
BadgeEntity,
|
BadgeEntity,
|
||||||
PersonText,
|
PersonText,
|
||||||
@ -222,15 +223,6 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getGenderIcon: function () {
|
|
||||||
return this.person.gender === 'woman' ? 'fa-venus' : this.person.gender === 'man' ? 'fa-mars' : this.person.gender === 'both' ? 'fa-neuter' : 'fa-genderless';
|
|
||||||
},
|
|
||||||
getGenderTranslation: function () {
|
|
||||||
return this.person.gender === 'woman' ? 'renderbox.birthday.woman' : 'renderbox.birthday.man';
|
|
||||||
},
|
|
||||||
getGender() {
|
|
||||||
return this.person.gender === 'woman' ? 'person.gender.woman' : this.person.gender === 'man' ? 'person.gender.man' : this.person.gender === 'both' ? 'person.gender.both' : 'person.gender.undefined';
|
|
||||||
},
|
|
||||||
birthdate: function () {
|
birthdate: function () {
|
||||||
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
if (this.person.birthdate !== null || this.person.birthdate === "undefined") {
|
||||||
return ISOToDate(this.person.birthdate.datetime);
|
return ISOToDate(this.person.birthdate.datetime);
|
||||||
|
@ -77,12 +77,11 @@
|
|||||||
class="form-select form-select-lg"
|
class="form-select form-select-lg"
|
||||||
id="gender"
|
id="gender"
|
||||||
v-model="gender"
|
v-model="gender"
|
||||||
@change="checkErrors"
|
|
||||||
>
|
>
|
||||||
<option selected disabled >{{ $t('person.gender.placeholder') }}</option>
|
<option selected disabled >{{ $t('person.gender.placeholder') }}</option>
|
||||||
<option value="woman">{{ $t('person.gender.woman') }}</option>
|
<option v-for="g in config.genders" :value="g.id" :key="g.id">
|
||||||
<option value="man">{{ $t('person.gender.man') }}</option>
|
{{ g.label.fr }}
|
||||||
<option value="both">{{ $t('person.gender.both') }}</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<label>{{ $t('person.gender.title') }}</label>
|
<label>{{ $t('person.gender.title') }}</label>
|
||||||
</div>
|
</div>
|
||||||
@ -178,7 +177,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getCentersForPersonCreation, getCivilities, getPerson, getPersonAltNames } from '../../_api/OnTheFly';
|
import { getCentersForPersonCreation, getCivilities, getGenders, getPerson, getPersonAltNames } from '../../_api/OnTheFly';
|
||||||
import PersonRenderBox from '../Entity/PersonRenderBox.vue';
|
import PersonRenderBox from '../Entity/PersonRenderBox.vue';
|
||||||
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
||||||
|
|
||||||
@ -204,6 +203,7 @@ export default {
|
|||||||
altNames: [],
|
altNames: [],
|
||||||
civilities: [],
|
civilities: [],
|
||||||
centers: [],
|
centers: [],
|
||||||
|
genders: []
|
||||||
},
|
},
|
||||||
showCenters: false, // NOTE: must remains false if the form is not in create mode
|
showCenters: false, // NOTE: must remains false if the form is not in create mode
|
||||||
showAddressFormValue: false,
|
showAddressFormValue: false,
|
||||||
@ -237,8 +237,8 @@ export default {
|
|||||||
get() { return this.person.lastName; }
|
get() { return this.person.lastName; }
|
||||||
},
|
},
|
||||||
gender: {
|
gender: {
|
||||||
set(value) { this.person.gender = value; },
|
set(value) { this.person.gender = {id: value, type: 'chill_main_gender'}; },
|
||||||
get() { return this.person.gender; }
|
get() { return this.person.gender ? this.person.gender.id : null; }
|
||||||
},
|
},
|
||||||
civility: {
|
civility: {
|
||||||
set(value) { this.person.civility = {id: value, type: 'chill_main_civility'}; },
|
set(value) { this.person.civility = {id: value, type: 'chill_main_civility'}; },
|
||||||
@ -300,13 +300,13 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
genderTranslation() {
|
genderTranslation() {
|
||||||
switch (this.person.gender) {
|
switch (this.person.gender.genderTranslation) {
|
||||||
case 'woman':
|
case 'woman':
|
||||||
return 'person.gender.woman';
|
return 'person.gender.woman';
|
||||||
case 'man':
|
case 'man':
|
||||||
return 'person.gender.man';
|
return 'person.gender.man';
|
||||||
case 'both':
|
case 'neutral':
|
||||||
return 'person.gender.both';
|
return 'person.gender.neutral';
|
||||||
case 'unknown':
|
case 'unknown':
|
||||||
return 'person.gender.unknown';
|
return 'person.gender.unknown';
|
||||||
default:
|
default:
|
||||||
@ -334,6 +334,12 @@ export default {
|
|||||||
this.config.civilities = civilities.results;
|
this.config.civilities = civilities.results;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
getGenders()
|
||||||
|
.then(genders => {
|
||||||
|
if ('results' in genders) {
|
||||||
|
this.config.genders = genders.results;
|
||||||
|
}
|
||||||
|
});
|
||||||
if (this.action !== 'create') {
|
if (this.action !== 'create') {
|
||||||
this.loadData();
|
this.loadData();
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,7 +15,7 @@ const personMessages = {
|
|||||||
person: {
|
person: {
|
||||||
firstname: "Prénom",
|
firstname: "Prénom",
|
||||||
lastname: "Nom",
|
lastname: "Nom",
|
||||||
born: (ctx: {gender: "man"|"woman"|"unknown"}) => {
|
born: (ctx: {gender: "man"|"woman"|"neutral"}) => {
|
||||||
if (ctx.gender === 'man') {
|
if (ctx.gender === 'man') {
|
||||||
return 'Né le';
|
return 'Né le';
|
||||||
} else if (ctx.gender === 'woman') {
|
} else if (ctx.gender === 'woman') {
|
||||||
@ -36,7 +36,7 @@ const personMessages = {
|
|||||||
placeholder: "Choisissez le genre de l'usager",
|
placeholder: "Choisissez le genre de l'usager",
|
||||||
woman: "Féminin",
|
woman: "Féminin",
|
||||||
man: "Masculin",
|
man: "Masculin",
|
||||||
both: "Neutre, non binaire",
|
neutral: "Neutre, non binaire",
|
||||||
unknown: "Non renseigné",
|
unknown: "Non renseigné",
|
||||||
undefined: "Non renseigné"
|
undefined: "Non renseigné"
|
||||||
},
|
},
|
||||||
|
@ -85,13 +85,8 @@
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
{%- if options['addInfo'] -%}
|
{%- if options['addInfo'] -%}
|
||||||
{% set gender = (person.gender == 'woman') ? 'fa-venus' :
|
|
||||||
(person.gender == 'man') ? 'fa-mars' : (person.gender == 'both') ? 'fa-neuter' : 'fa-genderless' %}
|
|
||||||
{% set genderTitle = (person.gender == 'woman') ? 'woman' :
|
|
||||||
(person.gender == 'man') ? 'man' : (person.gender == 'both') ? 'both' : 'Not given'|trans %}
|
|
||||||
<p class="moreinfo">
|
<p class="moreinfo">
|
||||||
<i class="fa fa-fw {{ gender }}" title="{{ genderTitle|trans }}"></i>
|
{% if person.gender is not null %}{{ person.gender.icon|chill_entity_render_box }}{% endif %}
|
||||||
|
|
||||||
{%- if person.deathdate is not null -%}
|
{%- if person.deathdate is not null -%}
|
||||||
{%- if person.birthdate is not null -%}
|
{%- if person.birthdate is not null -%}
|
||||||
{# must be on one line to avoid spaces with dash #}
|
{# must be on one line to avoid spaces with dash #}
|
||||||
@ -106,7 +101,7 @@
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- elseif person.birthdate is not null -%}
|
{%- elseif person.birthdate is not null -%}
|
||||||
<time datetime="{{ person.birthdate|date('Y-m-d') }}" title="{{ 'Birthdate'|trans }}">
|
<time datetime="{{ person.birthdate|date('Y-m-d') }}" title="{{ 'Birthdate'|trans }}">
|
||||||
{{ 'Born the date'|trans({'gender': person.gender,
|
{{ 'Born the date'|trans({'gender': person.gender ? person.gender.genderTranslation.value : 'neutral',
|
||||||
'birthdate': person.birthdate|format_date("medium") }) }}
|
'birthdate': person.birthdate|format_date("medium") }) }}
|
||||||
</time>
|
</time>
|
||||||
{%- if options['addAge'] -%}
|
{%- if options['addAge'] -%}
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<div class="ms-auto">
|
<div class="ms-auto">
|
||||||
{% if acp.requestoranonymous == false and acp.requestorPerson is same as(person) %}
|
{% if acp.requestoranonymous == false and acp.requestorPerson is same as(person) %}
|
||||||
<span class="as-requestor badge bg-info" title="{{ 'Requestor'|trans|e('html_attr') }}">
|
<span class="as-requestor badge bg-info" title="{{ 'Requestor'|trans|e('html_attr') }}">
|
||||||
{{ 'Requestor'|trans({'gender': person.gender}) }}
|
{{ 'Requestor'|trans({'gender': person.gender ? person.gender.genderTranslation.value : 'neutral'}) }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if participating %}
|
{% if participating %}
|
||||||
{{ 'person.and_himself'|trans({'gender': person.gender}) }}
|
{{ 'person.And himself'|trans({'gender': person.gender ? person.gender.genderTranslation.value : 'neutral'}) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -131,7 +131,7 @@
|
|||||||
<div class="wl-col title">
|
<div class="wl-col title">
|
||||||
<h3>
|
<h3>
|
||||||
{% if acp.requestorPerson is not null %}
|
{% if acp.requestorPerson is not null %}
|
||||||
{{ 'Requestor'|trans({'gender': acp.requestorPerson.gender}) }}
|
{{ 'Requestor'|trans({'gender': acp.requestorPerson.gender ? person.gender.genderTranslation.value : 'neutral'}) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ 'Requestor'|trans({'gender': 'other'})}}
|
{{ 'Requestor'|trans({'gender': 'other'})}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -73,8 +73,11 @@ This view should receive those arguments:
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<dt>{{ 'Gender'|trans }} :</dt>
|
<dt>{{ 'Gender'|trans }} :</dt>
|
||||||
<dd>{{ ( person.gender|default('Not given'))|trans }}</dd>
|
{% if person.gender %}
|
||||||
|
<dd>{{ ( person.gender.label|localize_translatable_string ) }}</dd>
|
||||||
|
{% else %}
|
||||||
|
<dd>{{ 'gender.not defined'|trans }}</dd>
|
||||||
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
</figure>
|
</figure>
|
||||||
</div>
|
</div>
|
||||||
@ -253,7 +256,6 @@ This view should receive those arguments:
|
|||||||
<dd>{% if el.description is not empty %}{{ el.description }} : {% endif %}<a href="tel:{{ el.phonenumber|phone_number_format('E164') }}">{{ el.phonenumber|chill_format_phonenumber }}</a></dd>
|
<dd>{% if el.description is not empty %}{{ el.description }} : {% endif %}<a href="tel:{{ el.phonenumber|phone_number_format('E164') }}">{{ el.phonenumber|chill_format_phonenumber }}</a></dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
|
||||||
</dl>
|
</dl>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>{{ 'gender'|trans }}</b>:
|
<li><b>{{ 'gender'|trans }}</b>:
|
||||||
{{ person.gender|trans }}</li>
|
{{ person.gender.label|localize_translatable_string }}</li>
|
||||||
<li><b>{{ 'maritalStatus'|trans }}</b>:
|
<li><b>{{ 'maritalStatus'|trans }}</b>:
|
||||||
{% if person.maritalStatus %}{{ person.maritalStatus.name|localize_translatable_string }}{% endif %}</li>
|
{% if person.maritalStatus %}{{ person.maritalStatus.name|localize_translatable_string }}{% endif %}</li>
|
||||||
<li><b>{{ 'birthdate'|trans }}</b>:
|
<li><b>{{ 'birthdate'|trans }}</b>:
|
||||||
|
@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Search;
|
|||||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||||
use Chill\MainBundle\Form\Type\ChillPhoneNumberType;
|
use Chill\MainBundle\Form\Type\ChillPhoneNumberType;
|
||||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||||
|
use Chill\MainBundle\Repository\GenderRepository;
|
||||||
use Chill\MainBundle\Search\AbstractSearch;
|
use Chill\MainBundle\Search\AbstractSearch;
|
||||||
use Chill\MainBundle\Search\HasAdvancedSearchFormInterface;
|
use Chill\MainBundle\Search\HasAdvancedSearchFormInterface;
|
||||||
use Chill\MainBundle\Search\ParsingException;
|
use Chill\MainBundle\Search\ParsingException;
|
||||||
@ -21,7 +22,7 @@ use Chill\MainBundle\Search\SearchInterface;
|
|||||||
use Chill\MainBundle\Search\Utils\ExtractDateFromPattern;
|
use Chill\MainBundle\Search\Utils\ExtractDateFromPattern;
|
||||||
use Chill\MainBundle\Search\Utils\ExtractPhonenumberFromPattern;
|
use Chill\MainBundle\Search\Utils\ExtractPhonenumberFromPattern;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Chill\PersonBundle\Form\Type\GenderType;
|
use Chill\PersonBundle\Form\Type\PickGenderType;
|
||||||
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
|
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
|
||||||
use libphonenumber\PhoneNumber;
|
use libphonenumber\PhoneNumber;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
@ -36,7 +37,14 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
'birthdate-after', 'gender', 'nationality', 'phonenumber', 'city',
|
'birthdate-after', 'gender', 'nationality', 'phonenumber', 'city',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(private readonly \Twig\Environment $templating, private readonly ExtractDateFromPattern $extractDateFromPattern, private readonly ExtractPhonenumberFromPattern $extractPhonenumberFromPattern, private readonly PaginatorFactory $paginatorFactory, private readonly PersonACLAwareRepositoryInterface $personACLAwareRepository) {}
|
public function __construct(
|
||||||
|
private readonly \Twig\Environment $templating,
|
||||||
|
private readonly ExtractDateFromPattern $extractDateFromPattern,
|
||||||
|
private readonly ExtractPhonenumberFromPattern $extractPhonenumberFromPattern,
|
||||||
|
private readonly PaginatorFactory $paginatorFactory,
|
||||||
|
private readonly PersonACLAwareRepositoryInterface $personACLAwareRepository,
|
||||||
|
private readonly GenderRepository $genderRepository,
|
||||||
|
) {}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder)
|
public function buildForm(FormBuilderInterface $builder)
|
||||||
{
|
{
|
||||||
@ -69,7 +77,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
'required' => false,
|
'required' => false,
|
||||||
'label' => 'Part of the phonenumber',
|
'label' => 'Part of the phonenumber',
|
||||||
])
|
])
|
||||||
->add('gender', GenderType::class, [
|
->add('gender', PickGenderType::class, [
|
||||||
'label' => 'Gender',
|
'label' => 'Gender',
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'expanded' => false,
|
'expanded' => false,
|
||||||
@ -87,7 +95,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
|
|
||||||
$string .= !isset($data['_default']) ? '' : $data['_default'].' ';
|
$string .= !isset($data['_default']) ? '' : $data['_default'].' ';
|
||||||
|
|
||||||
foreach (['firstname', 'lastname', 'gender', 'city'] as $key) {
|
foreach (['firstname', 'lastname', 'city'] as $key) {
|
||||||
$string .= !isset($data[$key]) ? '' : $key.':'.
|
$string .= !isset($data[$key]) ? '' : $key.':'.
|
||||||
// add quote if contains spaces
|
// add quote if contains spaces
|
||||||
(str_contains((string) $data[$key], ' ') ? '"'.$data[$key].'"' : $data[$key])
|
(str_contains((string) $data[$key], ' ') ? '"'.$data[$key].'"' : $data[$key])
|
||||||
@ -103,6 +111,8 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
|
|
||||||
$string .= !isset($data['phonenumber']) ? '' : 'phonenumber:'.$data['phonenumber']->getNationalNumber();
|
$string .= !isset($data['phonenumber']) ? '' : 'phonenumber:'.$data['phonenumber']->getNationalNumber();
|
||||||
|
|
||||||
|
$string .= !isset($data['gender']) ? '' : 'gender:"'.$data['gender']->getId().'"';
|
||||||
|
|
||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +120,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
{
|
{
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
foreach (['firstname', 'lastname', 'gender', '_default', 'phonenumber', 'city'] as $key) {
|
foreach (['firstname', 'lastname', '_default', 'phonenumber', 'city'] as $key) {
|
||||||
$data[$key] = $terms[$key] ?? null;
|
$data[$key] = $terms[$key] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +147,10 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
$data['phonenumber'] = $phonenumber;
|
$data['phonenumber'] = $phonenumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('gender', $terms)) {
|
||||||
|
$data['gender'] = $this->genderRepository->find((int) $terms['gender']);
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +270,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
$birthdate,
|
$birthdate,
|
||||||
$birthdateBefore,
|
$birthdateBefore,
|
||||||
$birthdateAfter,
|
$birthdateAfter,
|
||||||
$gender,
|
null !== $gender ? (int) $gender : null,
|
||||||
$countryCode,
|
$countryCode,
|
||||||
$phonenumber,
|
$phonenumber,
|
||||||
$city
|
$city
|
||||||
@ -316,7 +330,7 @@ class PersonSearch extends AbstractSearch implements HasAdvancedSearchFormInterf
|
|||||||
$birthdate,
|
$birthdate,
|
||||||
$birthdateBefore,
|
$birthdateBefore,
|
||||||
$birthdateAfter,
|
$birthdateAfter,
|
||||||
$gender,
|
null !== $gender ? (int) $gender : null,
|
||||||
$countryCode,
|
$countryCode,
|
||||||
$phonenumber,
|
$phonenumber,
|
||||||
$city
|
$city
|
||||||
|
@ -16,6 +16,7 @@ use Chill\DocGeneratorBundle\Serializer\Helper\NormalizeNullValueHelper;
|
|||||||
use Chill\MainBundle\Entity\Address;
|
use Chill\MainBundle\Entity\Address;
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Entity\Civility;
|
use Chill\MainBundle\Entity\Civility;
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||||
use Chill\PersonBundle\Entity\Household\Household;
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
@ -30,7 +31,6 @@ use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
|||||||
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
|
|
||||||
class PersonDocGenNormalizer implements
|
class PersonDocGenNormalizer implements
|
||||||
ContextAwareNormalizerInterface,
|
ContextAwareNormalizerInterface,
|
||||||
@ -40,7 +40,7 @@ class PersonDocGenNormalizer implements
|
|||||||
|
|
||||||
private const CIRCULAR_KEY = 'person:circular';
|
private const CIRCULAR_KEY = 'person:circular';
|
||||||
|
|
||||||
public function __construct(private readonly PersonRenderInterface $personRender, private readonly RelationshipRepository $relationshipRepository, private readonly TranslatorInterface $translator, private readonly TranslatableStringHelper $translatableStringHelper, private readonly SummaryBudgetInterface $summaryBudget) {}
|
public function __construct(private readonly PersonRenderInterface $personRender, private readonly RelationshipRepository $relationshipRepository, private readonly TranslatableStringHelper $translatableStringHelper, private readonly SummaryBudgetInterface $summaryBudget) {}
|
||||||
|
|
||||||
public function normalize($person, $format = null, array $context = [])
|
public function normalize($person, $format = null, array $context = [])
|
||||||
{
|
{
|
||||||
@ -67,6 +67,7 @@ class PersonDocGenNormalizer implements
|
|||||||
// when a person reference the same person... take care of circular references
|
// when a person reference the same person... take care of circular references
|
||||||
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => fn ($object, $format, $context) => $this->normalizer->normalize(null, $format, $context),
|
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => fn ($object, $format, $context) => $this->normalizer->normalize(null, $format, $context),
|
||||||
]);
|
]);
|
||||||
|
$genderContext = array_merge($context, ['docgen:expects' => Gender::class]);
|
||||||
|
|
||||||
if (null === $person) {
|
if (null === $person) {
|
||||||
return $this->normalizeNullValue($format, $context);
|
return $this->normalizeNullValue($format, $context);
|
||||||
@ -94,7 +95,7 @@ class PersonDocGenNormalizer implements
|
|||||||
'age' => (int) $person->getAge(),
|
'age' => (int) $person->getAge(),
|
||||||
'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $dateContext),
|
'birthdate' => $this->normalizer->normalize($person->getBirthdate(), $format, $dateContext),
|
||||||
'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $dateContext),
|
'deathdate' => $this->normalizer->normalize($person->getDeathdate(), $format, $dateContext),
|
||||||
'gender' => $this->translator->trans($person->getGender()),
|
'gender' => $this->normalizer->normalize($person->getGender(), $format, $genderContext),
|
||||||
'maritalStatus' => null !== ($ms = $person->getMaritalStatus()) ? $this->translatableStringHelper->localize($ms->getName()) : '',
|
'maritalStatus' => null !== ($ms = $person->getMaritalStatus()) ? $this->translatableStringHelper->localize($ms->getName()) : '',
|
||||||
'maritalStatusDate' => $this->normalizer->normalize($person->getMaritalStatusDate(), $format, $dateContext),
|
'maritalStatusDate' => $this->normalizer->normalize($person->getMaritalStatusDate(), $format, $dateContext),
|
||||||
'maritalStatusComment' => $this->normalizer->normalize($person->getMaritalStatusComment(), $format, $dateContext),
|
'maritalStatusComment' => $this->normalizer->normalize($person->getMaritalStatusComment(), $format, $dateContext),
|
||||||
|
@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Serializer\Normalizer;
|
|||||||
|
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
use Chill\MainBundle\Entity\Civility;
|
use Chill\MainBundle\Entity\Civility;
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
use Chill\MainBundle\Phonenumber\PhoneNumberHelperInterface;
|
use Chill\MainBundle\Phonenumber\PhoneNumberHelperInterface;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||||
use Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension;
|
use Chill\MainBundle\Templating\Entity\ChillEntityRenderExtension;
|
||||||
@ -112,7 +113,9 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'gender':
|
case 'gender':
|
||||||
$person->setGender($data[$item]);
|
$gender = $this->denormalizer->denormalize($data[$item], Gender::class, $format, []);
|
||||||
|
|
||||||
|
$person->setGender($gender);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -199,7 +202,7 @@ class PersonJsonNormalizer implements DenormalizerAwareInterface, NormalizerAwar
|
|||||||
'phonenumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $context),
|
'phonenumber' => $this->normalizer->normalize($person->getPhonenumber(), $format, $context),
|
||||||
'mobilenumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $context),
|
'mobilenumber' => $this->normalizer->normalize($person->getMobilenumber(), $format, $context),
|
||||||
'email' => $person->getEmail(),
|
'email' => $person->getEmail(),
|
||||||
'gender' => $person->getGender(),
|
'gender' => $this->normalizer->normalize($person->getGender(), $format, $context),
|
||||||
'civility' => $this->normalizer->normalize($person->getCivility(), $format, $context),
|
'civility' => $this->normalizer->normalize($person->getCivility(), $format, $context),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Tests\Controller\AccompanyingCoursWorkApiController;
|
namespace Tests\Controller\AccompanyingCoursWorkApiController;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Entity\GenderEnum;
|
||||||
|
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
@ -129,8 +132,15 @@ class ConflictTest extends WebTestCase
|
|||||||
|
|
||||||
$period = new AccompanyingPeriod();
|
$period = new AccompanyingPeriod();
|
||||||
$em->persist($period);
|
$em->persist($period);
|
||||||
|
|
||||||
|
$gender = new Gender();
|
||||||
|
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||||
|
$gender->setLabel(['fr' => 'homme']);
|
||||||
|
$gender->setIcon(GenderIconEnum::MALE);
|
||||||
|
$em->persist($gender);
|
||||||
|
|
||||||
$period->addPerson(($p = new Person())->setFirstName('test')->setLastName('test')
|
$period->addPerson(($p = new Person())->setFirstName('test')->setLastName('test')
|
||||||
->setBirthdate(new \DateTime('1980-01-01'))->setGender(Person::BOTH_GENDER));
|
->setBirthdate(new \DateTime('1980-01-01'))->setGender($gender));
|
||||||
$em->persist($p);
|
$em->persist($p);
|
||||||
$issue = (new SocialIssue())->setTitle(['fr' => 'test']);
|
$issue = (new SocialIssue())->setTitle(['fr' => 'test']);
|
||||||
$em->persist($issue);
|
$em->persist($issue);
|
||||||
|
@ -14,6 +14,9 @@ namespace Chill\PersonBundle\Tests\Controller;
|
|||||||
use Chill\MainBundle\Entity\Address;
|
use Chill\MainBundle\Entity\Address;
|
||||||
use Chill\MainBundle\Entity\AddressReference;
|
use Chill\MainBundle\Entity\AddressReference;
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Entity\GenderEnum;
|
||||||
|
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||||
use Chill\PersonBundle\Entity\Household\Household;
|
use Chill\PersonBundle\Entity\Household\Household;
|
||||||
@ -51,9 +54,15 @@ final class HouseholdApiControllerTest extends WebTestCase
|
|||||||
->setMaxResults(1)
|
->setMaxResults(1)
|
||||||
->getQuery()->getSingleResult();
|
->getQuery()->getSingleResult();
|
||||||
|
|
||||||
|
$gender = new Gender();
|
||||||
|
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||||
|
$gender->setLabel(['fr' => 'homme']);
|
||||||
|
$gender->setIcon(GenderIconEnum::MALE);
|
||||||
|
$em->persist($gender);
|
||||||
|
|
||||||
$p = new Person();
|
$p = new Person();
|
||||||
$p->setFirstname('test')->setLastName('test lastname')
|
$p->setFirstname('test')->setLastName('test lastname')
|
||||||
->setGender(Person::BOTH_GENDER)
|
->setGender($gender)
|
||||||
->setCenter($centerA);
|
->setCenter($centerA);
|
||||||
$em->persist($p);
|
$em->persist($p);
|
||||||
$h = new Household();
|
$h = new Household();
|
||||||
|
@ -112,11 +112,11 @@ final class PersonControllerCreateTest extends WebTestCase
|
|||||||
|
|
||||||
$genderType = $form->get(self::GENDER_INPUT);
|
$genderType = $form->get(self::GENDER_INPUT);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'radio',
|
'select',
|
||||||
$genderType->getType(),
|
$genderType->getType(),
|
||||||
'The gender input has radio buttons'
|
'The gender input is a select form to select a gender entity'
|
||||||
);
|
);
|
||||||
$this->assertEquals(
|
/* $this->assertEquals(
|
||||||
3,
|
3,
|
||||||
\count($genderType->availableOptionValues()),
|
\count($genderType->availableOptionValues()),
|
||||||
'The gender input has three options: man, women and undefined'
|
'The gender input has three options: man, women and undefined'
|
||||||
@ -129,7 +129,7 @@ final class PersonControllerCreateTest extends WebTestCase
|
|||||||
\in_array('woman', $genderType->availableOptionValues(), true),
|
\in_array('woman', $genderType->availableOptionValues(), true),
|
||||||
'gender has "femme" option'
|
'gender has "femme" option'
|
||||||
);
|
);
|
||||||
$this->assertFalse($genderType->hasValue(), 'The gender input is not checked');
|
$this->assertFalse($genderType->hasValue(), 'The gender input is not checked');*/
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
@ -226,7 +226,8 @@ final class PersonControllerCreateTest extends WebTestCase
|
|||||||
) {
|
) {
|
||||||
$creationForm->get(self::FIRSTNAME_INPUT)->setValue($firstname.'_'.uniqid());
|
$creationForm->get(self::FIRSTNAME_INPUT)->setValue($firstname.'_'.uniqid());
|
||||||
$creationForm->get(self::LASTNAME_INPUT)->setValue($lastname.'_'.uniqid());
|
$creationForm->get(self::LASTNAME_INPUT)->setValue($lastname.'_'.uniqid());
|
||||||
$creationForm->get(self::GENDER_INPUT)->select('man');
|
// Todo change hardcoded id
|
||||||
|
$creationForm->get(self::GENDER_INPUT)->select(5);
|
||||||
$date = $birthdate ?? new \DateTime('1947-02-01');
|
$date = $birthdate ?? new \DateTime('1947-02-01');
|
||||||
$creationForm->get(self::BIRTHDATE_INPUT)->setValue($date->format('Y-m-d'));
|
$creationForm->get(self::BIRTHDATE_INPUT)->setValue($date->format('Y-m-d'));
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ declare(strict_types=1);
|
|||||||
namespace Chill\PersonBundle\Tests\Controller;
|
namespace Chill\PersonBundle\Tests\Controller;
|
||||||
|
|
||||||
use Chill\MainBundle\Entity\Center;
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Entity\GenderEnum;
|
||||||
|
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
||||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
@ -160,12 +163,18 @@ final class PersonControllerUpdateTest extends WebTestCase
|
|||||||
$em = self::getContainer()->get(EntityManagerInterface::class);
|
$em = self::getContainer()->get(EntityManagerInterface::class);
|
||||||
$center = $centerRepository->findOneBy(['name' => 'Center A']);
|
$center = $centerRepository->findOneBy(['name' => 'Center A']);
|
||||||
|
|
||||||
|
$gender = new Gender();
|
||||||
|
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||||
|
$gender->setLabel(['fr' => 'homme']);
|
||||||
|
$gender->setIcon(GenderIconEnum::MALE);
|
||||||
|
$em->persist($gender);
|
||||||
|
|
||||||
$person = new Person();
|
$person = new Person();
|
||||||
$person
|
$person
|
||||||
->setFirstName('Foo')
|
->setFirstName('Foo')
|
||||||
->setLastName('Bar')
|
->setLastName('Bar')
|
||||||
->setBirthdate(new \DateTime('2017-09-30'))
|
->setBirthdate(new \DateTime('2017-09-30'))
|
||||||
->setGender(Person::MALE_GENDER)
|
->setGender($gender)
|
||||||
->setCenter($center);
|
->setCenter($center);
|
||||||
|
|
||||||
$em->persist($person);
|
$em->persist($person);
|
||||||
|
@ -11,6 +11,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\PersonBundle\Tests\Controller;
|
namespace Chill\PersonBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Gender;
|
||||||
|
use Chill\MainBundle\Entity\GenderEnum;
|
||||||
|
use Chill\MainBundle\Entity\GenderIconEnum;
|
||||||
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
use Chill\MainBundle\Repository\CenterRepositoryInterface;
|
||||||
use Chill\MainBundle\Test\PrepareClientTrait;
|
use Chill\MainBundle\Test\PrepareClientTrait;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
@ -99,12 +102,18 @@ final class PersonControllerViewTest extends WebTestCase
|
|||||||
$em = self::getContainer()->get(EntityManagerInterface::class);
|
$em = self::getContainer()->get(EntityManagerInterface::class);
|
||||||
$center = $centerRepository->findOneBy(['name' => 'Center A']);
|
$center = $centerRepository->findOneBy(['name' => 'Center A']);
|
||||||
|
|
||||||
|
$gender = new Gender();
|
||||||
|
$gender->setGenderTranslation(GenderEnum::MALE);
|
||||||
|
$gender->setLabel(['fr' => 'homme']);
|
||||||
|
$gender->setIcon(GenderIconEnum::MALE);
|
||||||
|
$em->persist($gender);
|
||||||
|
|
||||||
$person = new Person();
|
$person = new Person();
|
||||||
$person
|
$person
|
||||||
->setFirstName('Foo')
|
->setFirstName('Foo')
|
||||||
->setLastName('Bar')
|
->setLastName('Bar')
|
||||||
->setBirthdate(new \DateTime('2017-09-30'))
|
->setBirthdate(new \DateTime('2017-09-30'))
|
||||||
->setGender(Person::MALE_GENDER)
|
->setGender($gender)
|
||||||
->setCenter($center);
|
->setCenter($center);
|
||||||
|
|
||||||
$em->persist($person);
|
$em->persist($person);
|
||||||
|
@ -41,13 +41,13 @@ final class GenderFilterTest extends AbstractFilterTest
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
'accepted_genders' => [Person::FEMALE_GENDER],
|
'accepted_genders' => ['man'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'accepted_genders' => [Person::MALE_GENDER],
|
'accepted_genders' => ['woman'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'accepted_genders' => [Person::MALE_GENDER, Person::BOTH_GENDER],
|
'accepted_genders' => ['man', 'both'],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
|
|||||||
$personDocGenNormalizer = new PersonDocGenNormalizer(
|
$personDocGenNormalizer = new PersonDocGenNormalizer(
|
||||||
$personRender ?? self::getContainer()->get(PersonRender::class),
|
$personRender ?? self::getContainer()->get(PersonRender::class),
|
||||||
$relationshipRepository ?? self::getContainer()->get(RelationshipRepository::class),
|
$relationshipRepository ?? self::getContainer()->get(RelationshipRepository::class),
|
||||||
$translator ?? self::getContainer()->get(TranslatorInterface::class),
|
// $translator ?? self::getContainer()->get(TranslatorInterface::class),
|
||||||
$translatableStringHelper ?? self::getContainer()->get(TranslatableStringHelperInterface::class),
|
$translatableStringHelper ?? self::getContainer()->get(TranslatableStringHelperInterface::class),
|
||||||
$summaryBudget->reveal(),
|
$summaryBudget->reveal(),
|
||||||
);
|
);
|
||||||
@ -299,7 +299,7 @@ final class PersonDocGenNormalizerTest extends KernelTestCase
|
|||||||
$normalizer = new PersonDocGenNormalizer(
|
$normalizer = new PersonDocGenNormalizer(
|
||||||
$personRender ?? self::getContainer()->get(PersonRender::class),
|
$personRender ?? self::getContainer()->get(PersonRender::class),
|
||||||
$relationshipRepository,
|
$relationshipRepository,
|
||||||
$translator ?? self::getContainer()->get(TranslatorInterface::class),
|
// $translator ?? self::getContainer()->get(TranslatorInterface::class),
|
||||||
$translatableStringHelper ?? self::getContainer()->get(TranslatableStringHelperInterface::class),
|
$translatableStringHelper ?? self::getContainer()->get(TranslatableStringHelperInterface::class),
|
||||||
$summaryBudget->reveal()
|
$summaryBudget->reveal()
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Person;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20240926100337 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add foreign key gender property to person and transfer values';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_person_person ADD gender_id INT DEFAULT NULL');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_person ADD CONSTRAINT FK_BF210A14708A0E0 FOREIGN KEY (gender_id) REFERENCES chill_main_gender (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('CREATE INDEX IDX_BF210A14708A0E0 ON chill_person_person (gender_id)');
|
||||||
|
|
||||||
|
// transfer gender values to point to corresponding gender entity within new column
|
||||||
|
$this->addSql("
|
||||||
|
UPDATE chill_person_person AS p
|
||||||
|
SET gender_id = g.id
|
||||||
|
FROM chill_main_gender AS g
|
||||||
|
WHERE g.genderTranslation = p.gender AND p.gender IN ('man', 'woman', 'unknown')
|
||||||
|
OR (g.genderTranslation = 'neutral' AND p.gender = 'both')
|
||||||
|
");
|
||||||
|
|
||||||
|
// delete old gender column
|
||||||
|
$this->addSql('ALTER TABLE chill_person_person DROP gender');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_person_person ADD gender VARCHAR(9) DEFAULT NULL');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_person DROP gender_id');
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ Born the date: >-
|
|||||||
{gender, select,
|
{gender, select,
|
||||||
man {Né le {birthdate}}
|
man {Né le {birthdate}}
|
||||||
woman {Née le {birthdate}}
|
woman {Née le {birthdate}}
|
||||||
|
neutral {Né·e le {birthdate}}
|
||||||
other {Né·e le {birthdate}}
|
other {Né·e le {birthdate}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9,17 +10,18 @@ Requestor: >-
|
|||||||
{gender, select,
|
{gender, select,
|
||||||
man {Demandeur}
|
man {Demandeur}
|
||||||
woman {Demandeuse}
|
woman {Demandeuse}
|
||||||
other {Demandeur·euse}
|
neutral {Demandeur·euse}
|
||||||
}
|
}
|
||||||
|
|
||||||
person:
|
person:
|
||||||
and_himself: >-
|
from_the: depuis le
|
||||||
|
And himself: >-
|
||||||
{gender, select,
|
{gender, select,
|
||||||
man {et lui-même}
|
man {et lui-même}
|
||||||
woman {et elle-même}
|
woman {et elle-même}
|
||||||
|
neutral {et lui·elle-même}
|
||||||
other {et lui·elle-même}
|
other {et lui·elle-même}
|
||||||
}
|
}
|
||||||
from_the: depuis le
|
|
||||||
|
|
||||||
household:
|
household:
|
||||||
Household: Ménage
|
Household: Ménage
|
||||||
|
@ -64,6 +64,7 @@ Female: Femme
|
|||||||
#Both: Neutre
|
#Both: Neutre
|
||||||
man: Homme
|
man: Homme
|
||||||
woman: Femme
|
woman: Femme
|
||||||
|
neutral: Neutre
|
||||||
#both: Neutre
|
#both: Neutre
|
||||||
Man: Homme
|
Man: Homme
|
||||||
Woman: Femme
|
Woman: Femme
|
||||||
@ -1188,6 +1189,8 @@ export:
|
|||||||
date_after: Après le
|
date_after: Après le
|
||||||
date_before: Avant le
|
date_before: Avant le
|
||||||
title: Filtrer les usagers n'ayant été associés à aucun parcours
|
title: Filtrer les usagers n'ayant été associés à aucun parcours
|
||||||
|
gender:
|
||||||
|
no_gender: genre non specifié
|
||||||
|
|
||||||
course:
|
course:
|
||||||
not_having_address_reference:
|
not_having_address_reference:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user