diff --git a/.changes/unreleased/Feature-20241030-095713.yaml b/.changes/unreleased/Feature-20241030-095713.yaml new file mode 100644 index 000000000..391fcd878 --- /dev/null +++ b/.changes/unreleased/Feature-20241030-095713.yaml @@ -0,0 +1,5 @@ +kind: Feature +body: Introduce a gender entity +time: 2024-10-30T09:57:13.110347067+01:00 +custom: + Issue: "" diff --git a/package.json b/package.json index 0c932b9f6..8f741d3e9 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,8 @@ "vue-i18n": "^9.1.6", "vue-multiselect": "3.0.0-alpha.2", "vue-toast-notification": "^3.1.2", - "vuex": "^4.0.0" + "vuex": "^4.0.0", + "bootstrap-icons": "^1.11.3" }, "browserslist": [ "Firefox ESR" diff --git a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php index 21aa746aa..723b47612 100644 --- a/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php +++ b/src/Bundle/ChillCustomFieldsBundle/Entity/CustomFieldsGroup.php @@ -178,7 +178,7 @@ class CustomFieldsGroup * * @return CustomFieldsGroup */ - public function setName($name) + public function setName(array|string $name) { $this->name = $name; diff --git a/src/Bundle/ChillMainBundle/Controller/GenderApiController.php b/src/Bundle/ChillMainBundle/Controller/GenderApiController.php new file mode 100644 index 000000000..96fae4024 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/GenderApiController.php @@ -0,0 +1,32 @@ +andWhere( + $query->expr()->eq('e.active', "'TRUE'") + ); + } + + protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format) + { + return $query->addOrderBy('e.order', 'ASC'); + } +} diff --git a/src/Bundle/ChillMainBundle/Controller/GenderController.php b/src/Bundle/ChillMainBundle/Controller/GenderController.php new file mode 100644 index 000000000..a556145d4 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Controller/GenderController.php @@ -0,0 +1,26 @@ +addOrderBy('e.order', 'ASC'); + + return parent::orderQuery($action, $query, $request, $paginator); + } +} diff --git a/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php new file mode 100644 index 000000000..2d74e6977 --- /dev/null +++ b/src/Bundle/ChillMainBundle/DataFixtures/ORM/LoadGenders.php @@ -0,0 +1,63 @@ + ['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(); + } +} diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 9d788c64e..ca293cdd3 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -17,6 +17,8 @@ use Chill\MainBundle\Controller\CivilityApiController; use Chill\MainBundle\Controller\CivilityController; use Chill\MainBundle\Controller\CountryApiController; use Chill\MainBundle\Controller\CountryController; +use Chill\MainBundle\Controller\GenderApiController; +use Chill\MainBundle\Controller\GenderController; use Chill\MainBundle\Controller\GeographicalUnitApiController; use Chill\MainBundle\Controller\LanguageController; use Chill\MainBundle\Controller\LocationController; @@ -52,6 +54,7 @@ use Chill\MainBundle\Doctrine\Type\PointType; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Civility; use Chill\MainBundle\Entity\Country; +use Chill\MainBundle\Entity\Gender; use Chill\MainBundle\Entity\GeographicalUnitLayer; use Chill\MainBundle\Entity\Language; use Chill\MainBundle\Entity\Location; @@ -63,6 +66,7 @@ use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Form\CenterType; use Chill\MainBundle\Form\CivilityType; use Chill\MainBundle\Form\CountryType; +use Chill\MainBundle\Form\GenderType; use Chill\MainBundle\Form\LanguageType; use Chill\MainBundle\Form\LocationFormType; 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, '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, 'controller' => GeographicalUnitApiController::class, diff --git a/src/Bundle/ChillMainBundle/Entity/Gender.php b/src/Bundle/ChillMainBundle/Entity/Gender.php new file mode 100644 index 000000000..59c0bd134 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/Gender.php @@ -0,0 +1,104 @@ + 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; + } +} diff --git a/src/Bundle/ChillMainBundle/Entity/GenderEnum.php b/src/Bundle/ChillMainBundle/Entity/GenderEnum.php new file mode 100644 index 000000000..1fce6f2a6 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/GenderEnum.php @@ -0,0 +1,19 @@ +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) => '', + '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, + ]); + } +} diff --git a/src/Bundle/ChillMainBundle/Repository/GenderRepository.php b/src/Bundle/ChillMainBundle/Repository/GenderRepository.php new file mode 100644 index 000000000..56dcd1a4b --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/GenderRepository.php @@ -0,0 +1,47 @@ + + */ +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(); + } +} diff --git a/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js b/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js index a9d34e01d..91d66416a 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js +++ b/src/Bundle/ChillMainBundle/Resources/public/module/bootstrap/index.js @@ -10,6 +10,7 @@ import Modal from 'bootstrap/js/dist/modal'; import Collapse from 'bootstrap/js/src/collapse'; import Carousel from 'bootstrap/js/src/carousel'; 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 @@ -59,4 +60,4 @@ const popoverList = triggerList.map(function (el) { return new Popover(el, { html: true, }); -}); \ No newline at end of file +}); diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/GenderIconRenderBox.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/GenderIconRenderBox.vue new file mode 100644 index 000000000..2aeb123c7 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/Entity/GenderIconRenderBox.vue @@ -0,0 +1,11 @@ + + + diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts index f81699a7c..1e2844f3e 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.ts @@ -38,7 +38,8 @@ const messages = { person: "Usager", birthday: { man: "Né le", - woman: "Née le" + woman: "Née le", + neutral: "Né·e le" }, deathdate: "Date de décès", household_without_address: "Le ménage de l'usager est sans adresse", diff --git a/src/Bundle/ChillMainBundle/Resources/views/Gender/edit.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Gender/edit.html.twig new file mode 100644 index 000000000..39f01e519 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/views/Gender/edit.html.twig @@ -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 %} +
+ + + +
+ {% endfor %} +{% endblock %} + +{% block admin_content %} + {% set formId = crudMainFormId|default('crud_main_form') %} + + {% block crud_content_header %} +

{{ ('crud.'~crud_name~'.title_edit')|trans }}

+ {% 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 %} + + {% endblock %} + + {% endblock %} +{% endblock admin_content %} diff --git a/src/Bundle/ChillMainBundle/Resources/views/Gender/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Gender/index.html.twig new file mode 100644 index 000000000..8155e18ec --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/views/Gender/index.html.twig @@ -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 %} + id + {{ 'label'|trans }} + {{ 'icon'|trans }} + {{ 'gender.genderTranslation'|trans }} + {{ 'active'|trans }} + {{ 'ordering'|trans }} + + {% endblock %} + {% block table_entities_tbody %} + {% for entity in entities %} + + {{ entity.id }} + {{ entity.label|localize_translatable_string }} + {{ entity.icon|chill_entity_render_box }} + {{ entity.genderTranslation.value }} + + {%- if entity.active -%} + + {%- else -%} + + {%- endif -%} + + {{ entity.order }} + + + + + {% endfor %} + {% endblock %} + + {% block actions_before %} +
  • + {{'Back to the admin'|trans}} +
  • + {% endblock %} + {% endembed %} +{% endblock %} diff --git a/src/Bundle/ChillMainBundle/Resources/views/Gender/new.html.twig b/src/Bundle/ChillMainBundle/Resources/views/Gender/new.html.twig new file mode 100644 index 000000000..a07ebfa9d --- /dev/null +++ b/src/Bundle/ChillMainBundle/Resources/views/Gender/new.html.twig @@ -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 %} +
    + + + +
    + {% endfor %} +{% endblock %} + +{% block admin_content %} + {% set formId = crudMainFormId|default('crud_main_form') %} + + {% block crud_content_header %} +

    {{ ('crud.' ~ crud_name ~ '.title_new')|trans({'%crud_name%' : crud_name }) }}

    + {% 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 %} + + {% endblock %} + + {{ form_end(form) }} + {% endblock %} + +{% endblock admin_content %} diff --git a/src/Bundle/ChillMainBundle/Search/AbstractSearch.php b/src/Bundle/ChillMainBundle/Search/AbstractSearch.php index c4e0fecd9..a7c81d5bf 100644 --- a/src/Bundle/ChillMainBundle/Search/AbstractSearch.php +++ b/src/Bundle/ChillMainBundle/Search/AbstractSearch.php @@ -62,12 +62,12 @@ abstract class AbstractSearch implements SearchInterface $recomposed .= ' '.$term.':'; $containsSpace = str_contains((string) $terms[$term], ' '); - if ($containsSpace) { + if ($containsSpace || is_numeric($terms[$term])) { $recomposed .= '"'; } $recomposed .= (false === mb_stristr(' ', (string) $terms[$term])) ? $terms[$term] : '('.$terms[$term].')'; - if ($containsSpace) { + if ($containsSpace || is_numeric($terms[$term])) { $recomposed .= '"'; } } diff --git a/src/Bundle/ChillMainBundle/Templating/Entity/ChillGenderIconRender.php b/src/Bundle/ChillMainBundle/Templating/Entity/ChillGenderIconRender.php new file mode 100644 index 000000000..383234bd3 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Templating/Entity/ChillGenderIconRender.php @@ -0,0 +1,35 @@ + + */ +final readonly class ChillGenderIconRender implements ChillEntityRenderInterface +{ + public function renderBox($icon, array $options): string + { + return ''; + } + + public function renderString($icon, array $options): string + { + return $icon->value; + } + + public function supports($icon, array $options): bool + { + return $icon instanceof GenderIconEnum; + } +} diff --git a/src/Bundle/ChillMainBundle/config/services/templating.yaml b/src/Bundle/ChillMainBundle/config/services/templating.yaml index 0baa91b69..dc21b07f5 100644 --- a/src/Bundle/ChillMainBundle/config/services/templating.yaml +++ b/src/Bundle/ChillMainBundle/config/services/templating.yaml @@ -49,6 +49,8 @@ services: Chill\MainBundle\Templating\Entity\NewsItemRender: ~ + Chill\MainBundle\Templating\Entity\ChillGenderIconRender: ~ + Chill\MainBundle\Templating\Entity\UserRender: ~ Chill\MainBundle\Templating\Listing\: diff --git a/src/Bundle/ChillMainBundle/migrations/Version20240926093955.php b/src/Bundle/ChillMainBundle/migrations/Version20240926093955.php new file mode 100644 index 000000000..50da93e33 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20240926093955.php @@ -0,0 +1,69 @@ +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'); + } +} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 421cac473..3e6ea2011 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -43,6 +43,7 @@ lifecycleUpdate: Evenements de création et mise à jour address_fields: Données liées à l'adresse Datas: Données No title: Aucun titre +icon: icône user: profile: @@ -447,6 +448,12 @@ crud: title_delete: Supprimer une actualité button_delete: Supprimer 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 @@ -704,4 +711,8 @@ news: read_more: Lire la suite show_details: Voir l'actualité +gender: + genderTranslation: traduction grammaticale + not defined: Non défini + diff --git a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php index d356cf9ad..f1be52959 100644 --- a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php +++ b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadPeople.php @@ -15,11 +15,14 @@ use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes; use Chill\MainBundle\Entity\Address; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Country; +use Chill\MainBundle\Entity\Gender; +use Chill\MainBundle\Entity\GenderEnum; use Chill\MainBundle\Entity\PostalCode; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Repository\CenterRepository; use Chill\MainBundle\Repository\CountryRepository; +use Chill\MainBundle\Repository\GenderRepository; use Chill\MainBundle\Repository\ScopeRepository; use Chill\MainBundle\Repository\UserRepository; use Chill\PersonBundle\Entity\AccompanyingPeriod; @@ -77,12 +80,15 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord */ protected array $cacheUsers = []; + /** + * @var array|Gender[] + */ + protected array $cacheGenders = []; + protected Generator $faker; protected NativeLoader $loader; - private array $genders = [Person::MALE_GENDER, Person::FEMALE_GENDER, Person::BOTH_GENDER]; - private array $peoples = [ [ 'lastName' => 'Depardieu', @@ -90,7 +96,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord 'birthdate' => '1948-12-27', 'placeOfBirth' => 'Châteauroux', 'nationality' => 'RU', - 'gender' => Person::MALE_GENDER, + 'gender' => GenderEnum::MALE, 'center' => 'Center A', 'accompanyingPeriods' => [ [ @@ -119,7 +125,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord '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', 'firstName' => 'Bart', 'birthdate' => '1948-12-27', @@ -131,7 +137,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord 'lastName' => 'Depardieu', 'firstName' => 'Charline', 'birthdate' => '1970-10-15', - 'gender' => Person::FEMALE_GENDER, + 'gender' => GenderEnum::FEMALE, 'center' => 'Center A', 'maritalStatus' => 'ms_legalco', ], @@ -228,6 +234,7 @@ class LoadPeople extends AbstractFixture implements ContainerAwareInterface, Ord protected MaritalStatusRepository $maritalStatusRepository, protected ScopeRepository $scopeRepository, protected UserRepository $userRepository, + protected GenderRepository $genderRepository, ) { $this->faker = Factory::create('fr_FR'); $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 */ - 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)]; } /** diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index 0b4b54681..f26aa095e 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -21,6 +21,7 @@ use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Civility; use Chill\MainBundle\Entity\Country; use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; +use Chill\MainBundle\Entity\Gender; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\Language; use Chill\MainBundle\Entity\User; @@ -59,19 +60,11 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; #[HouseholdMembershipSequential(groups: ['household_memberships'])] class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateInterface, \Stringable { - final public const BOTH_GENDER = 'both'; - // have days in commun 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 FEMALE_GENDER = 'woman'; - - final public const MALE_GENDER = 'man'; - - final public const NO_INFORMATION = 'unknown'; - /** * Accept receiving email. */ @@ -242,11 +235,11 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI private ?string $fullnameCanonical = ''; /** - * The person's gender. + * NEW column : The person's gender. */ #[Assert\NotNull(message: 'The gender must be set')] - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 9, nullable: true)] - private ?string $gender = null; + #[ORM\ManyToOne(targetEntity: Gender::class)] + private ?Gender $gender = null; /** * Comment on gender. @@ -1003,7 +996,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI return $this->fullnameCanonical; } - public function getGender(): ?string + public function getGender(): ?Gender { return $this->gender; } @@ -1013,24 +1006,6 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI 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 { return $this->householdAddresses; @@ -1532,7 +1507,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI return $this; } - public function setGender(?string $gender): self + public function setGender(?Gender $gender): self { $this->gender = $gender; diff --git a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php index 0181c6e7b..f7ae26dca 100644 --- a/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php +++ b/src/Bundle/ChillPersonBundle/Export/Aggregator/PersonAggregators/GenderAggregator.php @@ -12,7 +12,8 @@ declare(strict_types=1); namespace Chill\PersonBundle\Export\Aggregator\PersonAggregators; 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 Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\FormBuilderInterface; @@ -20,7 +21,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; 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 { @@ -29,7 +30,8 @@ final readonly class GenderAggregator implements AggregatorInterface 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'); } @@ -48,30 +50,20 @@ final readonly class GenderAggregator implements AggregatorInterface public function getLabels($key, array $values, $data) { - return function ($value) { - switch ($value) { - case Person::FEMALE_GENDER: - 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)); + return function (int|string|null $value) { + if (null === $value || '' === $value) { + return ''; } + + if ('_header' === $value) { + return $this->translator->trans('Gender'); + } + + if (null === $gender = $this->repository->find((int) $value)) { + return ''; + } + + return (string) $this->translatableStringHelper->localize($gender->getLabel()); }; } diff --git a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php index 5009e37d0..fc09e385a 100644 --- a/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php +++ b/src/Bundle/ChillPersonBundle/Export/Filter/PersonFilters/GenderFilter.php @@ -11,11 +11,13 @@ declare(strict_types=1); 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\FilterInterface; -use Chill\PersonBundle\Entity\Person; +use Chill\MainBundle\Repository\GenderRepository; +use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Export\Declarations; -use Doctrine\ORM\Query\Expr; use Doctrine\ORM\QueryBuilder; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; @@ -24,17 +26,15 @@ use Symfony\Contracts\Translation\TranslatorInterface; class GenderFilter implements ExportElementValidatedInterface, - FilterInterface + FilterInterface, + DataTransformerInterface { - /** - * @var TranslatorInterface - */ - protected $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } + // inject gender repository and find the active genders so that you can pass them to the ChoiceType (ordered by ordering) + public function __construct( + private readonly TranslatorInterface $translator, + private readonly TranslatableStringHelperInterface $translatableStringHelper, + private readonly GenderRepository $genderRepository, + ) {} public function addRole(): ?string { @@ -46,23 +46,17 @@ class GenderFilter implements $where = $qb->getDQLPart('where'); $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; } else { $clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender')); } - if ($where instanceof Expr\Andx) { - $where->add($clause); - } else { - $where = $qb->expr()->andX($clause); - } - - $qb->add('where', $where); - $qb->setParameter('person_gender', \array_filter( - $data['accepted_genders'], - static fn ($el) => 'null' !== $el - )); + $qb->andWhere($clause); + $qb->setParameter('person_gender', array_filter($acceptedGenders ?? [], fn ($gender) => null !== $gender)); } public function applyOn() @@ -72,19 +66,42 @@ class GenderFilter implements public function buildForm(FormBuilderInterface $builder) { - $builder->add('accepted_genders', ChoiceType::class, [ - 'choices' => [ - 'Woman' => Person::FEMALE_GENDER, - 'Man' => Person::MALE_GENDER, - 'Both' => Person::BOTH_GENDER, - 'Unknown' => Person::NO_INFORMATION, - 'Not given' => 'null', - ], + $genderChoices = $this->genderRepository->findByActiveOrdered(); + $choices = ['None' => null]; + + foreach ($genderChoices as $gender) { + $choices[$this->translatableStringHelper->localize($gender->getLabel())] = $gender->getId(); + } + + $builder->add('accepted_genders_entity', ChoiceType::class, [ + 'choices' => $choices, 'multiple' => 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 { return []; @@ -94,11 +111,11 @@ class GenderFilter implements { $genders = []; - foreach ($data['accepted_genders'] as $g) { - if ('null' === $g) { - $genders[] = $this->translator->trans('Not given'); + foreach ($data['accepted_genders_entity'] as $g) { + if (null === $g) { + $genders[] = $this->translator->trans('export.filter.person.gender.no_gender'); } 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) { - 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') ->addViolation(); } diff --git a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php index 393d246ea..0c270a7ca 100644 --- a/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php +++ b/src/Bundle/ChillPersonBundle/Export/Helper/ListPersonHelper.php @@ -16,6 +16,7 @@ use Chill\MainBundle\Export\Helper\ExportAddressHelper; use Chill\MainBundle\Repository\CenterRepositoryInterface; use Chill\MainBundle\Repository\CivilityRepositoryInterface; use Chill\MainBundle\Repository\CountryRepository; +use Chill\MainBundle\Repository\GenderRepository; use Chill\MainBundle\Repository\LanguageRepositoryInterface; use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Templating\TranslatableStringHelper; @@ -80,6 +81,7 @@ final readonly class ListPersonHelper private TranslatableStringHelper $translatableStringHelper, private TranslatorInterface $translator, private UserRepositoryInterface $userRepository, + private GenderRepository $genderRepository, /** * @var iterable */ @@ -173,6 +175,11 @@ final readonly class ListPersonHelper break; + case 'gender': + $qb->addSelect('IDENTITY(person.gender) AS gender'); + + break; + case '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($value); + if (null === $value) { + return ''; + } + + $gender = $this->genderRepository->find($value); + + return $this->translatableStringHelper->localize($gender->getLabel()); }; case 'maritalStatus': diff --git a/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php b/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php index 9bfb75e31..bb40c6c35 100644 --- a/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php +++ b/src/Bundle/ChillPersonBundle/Form/CreationPersonType.php @@ -20,8 +20,8 @@ use Chill\MainBundle\Form\Type\PickCenterType; use Chill\MainBundle\Form\Type\PickCivilityType; use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper; use Chill\PersonBundle\Entity\Person; -use Chill\PersonBundle\Form\Type\GenderType; use Chill\PersonBundle\Form\Type\PersonAltNameType; +use Chill\PersonBundle\Form\Type\PickGenderType; use Chill\PersonBundle\Security\Authorization\PersonVoter; use libphonenumber\PhoneNumberType; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; @@ -60,7 +60,7 @@ final class CreationPersonType extends AbstractType 'label' => 'Civility', 'placeholder' => 'choose civility', ]) - ->add('gender', GenderType::class, [ + ->add('gender', PickGenderType::class, [ 'required' => true, 'placeholder' => null, ]) ->add('birthdate', ChillDateType::class, [ diff --git a/src/Bundle/ChillPersonBundle/Form/PersonType.php b/src/Bundle/ChillPersonBundle/Form/PersonType.php index 21717a25b..0f4fbd8e4 100644 --- a/src/Bundle/ChillPersonBundle/Form/PersonType.php +++ b/src/Bundle/ChillPersonBundle/Form/PersonType.php @@ -24,9 +24,9 @@ use Chill\MainBundle\Templating\TranslatableStringHelperInterface; use Chill\PersonBundle\Config\ConfigPersonAltNamesHelper; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\PersonPhone; -use Chill\PersonBundle\Form\Type\GenderType; use Chill\PersonBundle\Form\Type\PersonAltNameType; use Chill\PersonBundle\Form\Type\PersonPhoneType; +use Chill\PersonBundle\Form\Type\PickGenderType; use Chill\PersonBundle\Form\Type\Select2MaritalStatusType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\CallbackTransformer; @@ -80,7 +80,7 @@ class PersonType extends AbstractType 'input' => 'datetime_immutable', 'widget' => 'single_text', ]) - ->add('gender', GenderType::class, [ + ->add('gender', PickGenderType::class, [ 'required' => true, ]) ->add('genderComment', CommentType::class, [ diff --git a/src/Bundle/ChillPersonBundle/Form/Type/GenderType.php b/src/Bundle/ChillPersonBundle/Form/Type/GenderType.php deleted file mode 100644 index 2989b3ec4..000000000 --- a/src/Bundle/ChillPersonBundle/Form/Type/GenderType.php +++ /dev/null @@ -1,44 +0,0 @@ - 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; - } -} diff --git a/src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php b/src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php new file mode 100644 index 000000000..1e0c004d5 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Form/Type/PickGenderType.php @@ -0,0 +1,51 @@ +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; + } +} diff --git a/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php index ee2dad9dc..c3d369f00 100644 --- a/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/AdminPersonMenuBuilder.php @@ -45,13 +45,17 @@ class AdminPersonMenuBuilder implements LocalMenuBuilderInterface 'route' => 'chill_crud_main_civility_index', ])->setExtras(['order' => 2010]); + $menu->addChild('Gender', [ + 'route' => 'chill_crud_main_gender_index', + ])->setExtras(['order' => 2020]); + $menu->addChild('Marital status', [ 'route' => 'chill_crud_person_marital-status_index', - ])->setExtras(['order' => 2020]); + ])->setExtras(['order' => 2030]); $menu->addChild('person_admin.person_resource_kind', [ 'route' => 'chill_crud_person_resource-kind_index', - ])->setExtras(['order' => 2030]); + ])->setExtras(['order' => 2040]); } public static function getMenuIds(): array diff --git a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php index 9e76dd374..686022ca3 100644 --- a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php +++ b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepository.php @@ -34,7 +34,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor ?\DateTimeInterface $birthdate = null, ?\DateTimeInterface $birthdateBefore = null, ?\DateTimeInterface $birthdateAfter = null, - ?string $gender = null, + ?int $gender = null, ?string $countryCode = null, ?string $phonenumber = null, ?string $city = null, @@ -62,7 +62,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor ?\DateTimeInterface $birthdate = null, ?\DateTimeInterface $birthdateBefore = null, ?\DateTimeInterface $birthdateAfter = null, - ?string $gender = null, + ?int $gender = null, ?string $countryCode = null, ?string $phonenumber = null, ?string $city = null, @@ -96,7 +96,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor ?\DateTimeInterface $birthdate = null, ?\DateTimeInterface $birthdateBefore = null, ?\DateTimeInterface $birthdateAfter = null, - ?string $gender = null, + ?int $gender = null, ?string $countryCode = null, ?string $phonenumber = null, ?string $city = null, @@ -202,7 +202,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor } if (null !== $gender) { - $query->andWhereClause('person.gender = ?', [$gender]); + $query->andWhereClause('person.gender_id = ?', [$gender]); } return $query; @@ -253,7 +253,7 @@ final readonly class PersonACLAwareRepository implements PersonACLAwareRepositor ?\DateTimeInterface $birthdate = null, ?\DateTimeInterface $birthdateBefore = null, ?\DateTimeInterface $birthdateAfter = null, - ?string $gender = null, + ?int $gender = null, ?string $countryCode = null, ?string $phonenumber = null, ?string $city = null, diff --git a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php index 7a45d6648..50fdcd4b3 100644 --- a/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php +++ b/src/Bundle/ChillPersonBundle/Repository/PersonACLAwareRepositoryInterface.php @@ -23,7 +23,7 @@ interface PersonACLAwareRepositoryInterface ?\DateTimeInterface $birthdate = null, ?\DateTimeInterface $birthdateBefore = null, ?\DateTimeInterface $birthdateAfter = null, - ?string $gender = null, + ?int $gender = null, ?string $countryCode = null, ?string $phonenumber = null, ?string $city = null, @@ -36,7 +36,7 @@ interface PersonACLAwareRepositoryInterface ?\DateTimeInterface $birthdate = null, ?\DateTimeInterface $birthdateBefore = null, ?\DateTimeInterface $birthdateAfter = null, - ?string $gender = null, + ?int $gender = null, ?string $countryCode = null, ?string $phonenumber = null, ?string $city = null, @@ -55,7 +55,7 @@ interface PersonACLAwareRepositoryInterface ?\DateTimeInterface $birthdate = null, ?\DateTimeInterface $birthdateBefore = null, ?\DateTimeInterface $birthdateAfter = null, - ?string $gender = null, + ?int $gender = null, ?string $countryCode = null, ?string $phonenumber = null, ?string $city = null, diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue index 155fd6c46..a278d00c4 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/PersonsAssociated/ParticipationItem.vue @@ -128,7 +128,7 @@ export default { body.mobilenumber = payload.data.mobilenumber; body.email = payload.data.email; 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 }; } makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue index c2368d9ab..920287b86 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/Resources/ResourceItem.vue @@ -153,7 +153,7 @@ export default { body.mobilenumber = payload.data.mobilenumber; body.email = payload.data.email; 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}; } makeFetch('PATCH', `/api/1.0/person/person/${payload.data.id}.json`, body) diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue index 2258d8b77..fd2ef7bdb 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/MemberDetails.vue @@ -8,7 +8,7 @@ {{ $t('household_members_editor.holder') }} -
    {{ $t('person.born', {'gender': conc.person.gender} ) }}
    +
    {{ $t('person.born', {'gender': conc.person.gender.genderTranslation} ) }}

    - - +

    - + > + + +
    @@ -178,7 +177,7 @@