diff --git a/CHANGELOG.md b/CHANGELOG.md index a983ac15b..78cc7e038 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,7 @@ and this project adheres to * [main] increase length of 4 Address fields (change to TEXT, no size limits) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/277) * [main] Add confidential option for address, in edit and view (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/165) * [person] name suggestions within create person form when person is created departing from a search input (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/377) - - +* [person] Add residential address entity, form and list for each person ## Test releases ### test release 2021-01-26 diff --git a/src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php b/src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php new file mode 100644 index 000000000..7763ea9d5 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Entity/ResidentialAddress.php @@ -0,0 +1,166 @@ +comment = new CommentEmbeddable(); + } + + public function getAddress(): ?Address + { + return $this->address; + } + + public function getComment(): CommentEmbeddable + { + return $this->comment; + } + + public function getEndDate(): ?DateTimeImmutable + { + return $this->endDate; + } + + public function getHostPerson(): ?Person + { + return $this->hostPerson; + } + + public function getHostThirdParty(): ?ThirdParty + { + return $this->hostThirdParty; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getPerson(): ?Person + { + return $this->person; + } + + public function getStartDate(): ?DateTimeImmutable + { + return $this->startDate; + } + + public function setAddress(?Address $address): self + { + $this->address = $address; + + return $this; + } + + public function setComment(CommentEmbeddable $comment): self + { + $this->comment = $comment; + + return $this; + } + + public function setEndDate(?DateTimeImmutable $endDate): self + { + $this->endDate = $endDate; + + return $this; + } + + public function setHostPerson(?Person $hostPerson): self + { + $this->hostPerson = $hostPerson; + + return $this; + } + + public function setHostThirdParty(?ThirdParty $hostThirdParty): self + { + $this->hostThirdParty = $hostThirdParty; + + return $this; + } + + public function setPerson(?Person $person): self + { + $this->person = $person; + + return $this; + } + + public function setStartDate(DateTimeImmutable $startDate): self + { + $this->startDate = $startDate; + + return $this; + } +} diff --git a/src/Bundle/ChillMainBundle/Form/Type/ResidentialAddressType.php b/src/Bundle/ChillMainBundle/Form/Type/ResidentialAddressType.php new file mode 100644 index 000000000..0ebe47fef --- /dev/null +++ b/src/Bundle/ChillMainBundle/Form/Type/ResidentialAddressType.php @@ -0,0 +1,73 @@ +add('startDate', DateType::class, [ + 'required' => true, + 'input' => 'datetime_immutable', + 'widget' => 'single_text', + ]) + ->add('endDate', DateType::class, [ + 'required' => false, + 'input' => 'datetime_immutable', + 'widget' => 'single_text', + ]) + ->add('comment', CommentType::class, [ + 'required' => false, + ]); + + if ('person' === $options['kind']) { + $builder + ->add('hostPerson', PickPersonDynamicType::class, [ + 'label' => 'Person', + ]); + } + + if ('thirdparty' === $options['kind']) { + $builder + ->add('hostThirdParty', PickThirdpartyDynamicType::class, [ + 'label' => 'Third party', + ]); + } + + if ('address' === $options['kind']) { + $builder + ->add('address', PickAddressType::class, [ + 'required' => false, + 'label' => 'Address', + 'use_valid_from' => false, + 'use_valid_to' => false, + ]); + } + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => ResidentialAddress::class, + 'kind' => null, + ]); + } +} diff --git a/src/Bundle/ChillMainBundle/Repository/ResidentialAddressRepository.php b/src/Bundle/ChillMainBundle/Repository/ResidentialAddressRepository.php new file mode 100644 index 000000000..05cdfdf6c --- /dev/null +++ b/src/Bundle/ChillMainBundle/Repository/ResidentialAddressRepository.php @@ -0,0 +1,59 @@ +createQueryBuilder('r') + ->andWhere('r.exampleField = :val') + ->setParameter('val', $value) + ->orderBy('r.id', 'ASC') + ->setMaxResults(10) + ->getQuery() + ->getResult() + ; + } + */ + + /* + public function findOneBySomeField($value): ?ResidentialAddress + { + return $this->createQueryBuilder('r') + ->andWhere('r.exampleField = :val') + ->setParameter('val', $value) + ->getQuery() + ->getOneOrNullResult() + ; + } + */ +} diff --git a/src/Bundle/ChillMainBundle/migrations/Version20220125134253.php b/src/Bundle/ChillMainBundle/migrations/Version20220125134253.php new file mode 100644 index 000000000..7bcf003f9 --- /dev/null +++ b/src/Bundle/ChillMainBundle/migrations/Version20220125134253.php @@ -0,0 +1,48 @@ +addSql('DROP SEQUENCE chill_main_residential_address_id_seq CASCADE'); + $this->addSql('DROP TABLE chill_main_residential_address'); + } + + public function getDescription(): string + { + return 'Create a new entity ResidentialAddress'; + } + + public function up(Schema $schema): void + { + $this->addSql('CREATE SEQUENCE chill_main_residential_address_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE chill_main_residential_address (id INT NOT NULL, person_id INT NOT NULL, address_id INT DEFAULT NULL, startDate TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, endDate TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, residentialAddressComment_comment TEXT DEFAULT NULL, residentialAddressComment_date TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, residentialAddressComment_userId INT DEFAULT NULL, hostPerson_id INT DEFAULT NULL, hostThirdParty_id INT DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_9BC1FD50217BBB47 ON chill_main_residential_address (person_id)'); + $this->addSql('CREATE INDEX IDX_9BC1FD50DCA38092 ON chill_main_residential_address (hostPerson_id)'); + $this->addSql('CREATE INDEX IDX_9BC1FD508DFC48DC ON chill_main_residential_address (hostThirdParty_id)'); + $this->addSql('CREATE INDEX IDX_9BC1FD50F5B7AF75 ON chill_main_residential_address (address_id)'); + $this->addSql('COMMENT ON COLUMN chill_main_residential_address.startDate IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN chill_main_residential_address.endDate IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD50217BBB47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD50DCA38092 FOREIGN KEY (hostPerson_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD508DFC48DC FOREIGN KEY (hostThirdParty_id) REFERENCES chill_3party.third_party (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_main_residential_address ADD CONSTRAINT FK_9BC1FD50F5B7AF75 FOREIGN KEY (address_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + } +} diff --git a/src/Bundle/ChillMainBundle/translations/messages.fr.yml b/src/Bundle/ChillMainBundle/translations/messages.fr.yml index 5c214367c..e8bd44dc5 100644 --- a/src/Bundle/ChillMainBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillMainBundle/translations/messages.fr.yml @@ -52,6 +52,8 @@ Since %date%: Depuis le %date% since %date%: depuis le %date% Until %date%: Jusqu'au %date% until %date%: jusqu'au %date% +Since: Depuis le +Until: Jusqu'au #elements used in software centers: centres Centers: Centres diff --git a/src/Bundle/ChillPersonBundle/Controller/ResidentialAddressController.php b/src/Bundle/ChillPersonBundle/Controller/ResidentialAddressController.php new file mode 100644 index 000000000..8b266208a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Controller/ResidentialAddressController.php @@ -0,0 +1,161 @@ +generator = $generator; + $this->translator = $translator; + $this->residentialAddressRepository = $residentialAddressRepository; + } + + /** + * @Route("/{_locale}/person/residential-address/{id}/delete", name="chill_person_residential_address_delete") + */ + public function deleteAction(Request $request, ResidentialAddress $residentialAddress): Response + { + $this->denyAccessUnlessGranted(PersonVoter::UPDATE, $residentialAddress->getPerson()); + + $form = $this->createForm(FormType::class); + $form->add('submit', SubmitType::class, ['label' => 'Delete']); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->remove($residentialAddress); + $em->flush(); + + $this->addFlash('success', $this->translator->trans('Residential address had been deleted')); + + return $this->redirectToRoute('chill_person_residential_address_list', ['id' => $residentialAddress->getPerson()->getId()]); + } + + return $this->render('@ChillPerson/ResidentialAddress/delete.html.twig', [ + 'person' => $residentialAddress->getPerson(), + 'residentialAddress' => $residentialAddress, + 'delete_form' => $form->createView(), + ]); + } + + /** + * @Route("/{_locale}/person/residential-address/{id}/edit", name="chill_person_residential_address_edit") + */ + public function editAction(Request $request, ResidentialAddress $residentialAddress): Response + { + if ($request->query->has('kind')) { + $kind = $request->query->getAlpha('kind', ''); + } else { + $kind = null; + } + + $person = $residentialAddress->getPerson(); + $this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person); + + $form = $this->createForm(ResidentialAddressType::class, $residentialAddress, ['kind' => $kind]); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->getDoctrine()->getManager()->flush(); + + $this->addFlash('success', $this->translator + ->trans('The residential address was updated successfully')); + + return $this->redirect( + $request->get('returnPath', null) ?? + $this->generator->generate('chill_person_residential_address_list', ['id' => $person->getId()]) + ); + } + + return $this->render('@ChillPerson/ResidentialAddress/edit.html.twig', [ + 'residentialAddress' => $residentialAddress, + 'person' => $person, + 'form' => $form->createView(), + ]); + } + + /** + * @Route("/{_locale}/person/{id}/residential-address/list", name="chill_person_residential_address_list") + */ + public function listAction(Request $request, Person $person): Response + { + $this->denyAccessUnlessGranted(PersonVoter::SEE, $person); + + $residentialAddresses = $this->residentialAddressRepository->findBy(['person' => $person], ['startDate' => 'DESC']); + + return $this->render('@ChillPerson/ResidentialAddress/list.html.twig', [ + 'person' => $person, + 'addresses' => $residentialAddresses, + ]); + } + + /** + * @Route("/{_locale}/person/{id}/residential-address/new", name="chill_person_residential_address_new") + */ + public function newAction(Request $request, Person $person): Response + { + $residentialAddress = new ResidentialAddress(); + $residentialAddress->setPerson($person); + + $this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person); + + if (!$request->query->has('kind')) { + return $this->render('@ChillPerson/ResidentialAddress/new_pick_kind.html.twig', ['person' => $person]); + } + $kind = $request->query->getAlpha('kind', ''); + + $form = $this->createForm(ResidentialAddressType::class, $residentialAddress, ['kind' => $kind]); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->getDoctrine()->getManager()->persist($residentialAddress); + $this->getDoctrine()->getManager()->flush(); + + $this->addFlash('success', $this->translator + ->trans('The new residential address was created successfully')); + + return $this->redirect( + $request->get('returnPath', null) ?? + $this->generator->generate('chill_person_residential_address_list', ['id' => $residentialAddress->getPerson()->getId()]) + ); + } + + return $this->render('@ChillPerson/ResidentialAddress/new.html.twig', [ + 'person' => $person, + 'form' => $form->createView(), + ]); + } +} diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index c588b70a3..e908dc489 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -784,12 +784,18 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * If the `$at` parameter is now, use the method `getCurrentPersonAddress`, which is optimized * on database side. * + * @deprecated since chill2.0, address is linked to the household. Use @see{Person::getCurrentHouseholdAddress} + * * @throws Exception */ - public function getAddressAt(?DateTime $at = null): ?Address + public function getAddressAt(?DateTimeInterface $at = null): ?Address { $at ??= new DateTime('now'); + if ($at instanceof DateTimeImmutable) { + $at = DateTime::createFromImmutable($at); + } + /** @var ArrayIterator $addressesIterator */ $addressesIterator = $this->getAddresses() ->filter(static fn (Address $address): bool => $address->getValidFrom() <= $at) @@ -950,6 +956,12 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI : null; } + /** + * Get the household address at the given date. + * + * if the given date is 'now', use instead @see{getCurrentPersonAddress}, which is optimized on + * database side. + */ public function getCurrentHouseholdAddress(?DateTimeImmutable $at = null): ?Address { if ( diff --git a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php index 229b2d373..16422f47c 100644 --- a/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/PersonMenuBuilder.php @@ -62,6 +62,16 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface 'order' => 50, ]); + $menu->addChild($this->translator->trans('Residential addresses'), [ + 'route' => 'chill_person_residential_address_list', + 'routeParameters' => [ + 'id' => $parameters['person']->getId(), + ], + ]) + ->setExtras([ + 'order' => 60, + ]); + $menu->addChild($this->translator->trans('household.person history'), [ 'route' => 'chill_person_household_person_history', 'routeParameters' => [ diff --git a/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/_form.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/_form.html.twig new file mode 100644 index 000000000..22add892d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/_form.html.twig @@ -0,0 +1,37 @@ + + +{{ form_start(form) }} + +{{ form_row(form.startDate) }} +{{ form_row(form.endDate) }} + +{% if form.hostPerson is defined %} + {{ form_row(form.hostPerson) }} +{% endif %} + +{% if form.hostThirdParty is defined %} + {{ form_row(form.hostThirdParty) }} +{% endif %} + +{% if form.address is defined %} + {{ form_row(form.address) }} + + {% block js %} + {{ encore_entry_script_tags('mod_input_address') }} + {% endblock %} + + {% block css %} + {{ encore_entry_link_tags('mod_input_address') }} + {% endblock %} +{% endif %} + +{{ form_row(form.comment) }} + + + + +{{ form_end(form) }} \ No newline at end of file diff --git a/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/delete.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/delete.html.twig new file mode 100644 index 000000000..3171af58d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/delete.html.twig @@ -0,0 +1,58 @@ +{% extends "@ChillPerson/Person/layout.html.twig" %} + +{% set activeRouteKey = '' %} + +{% block title %}{{ 'Delete residential address'|trans }}{% endblock %} + +{% block personcontent %} +
+ +

{{ block('title') }}

+ {% set a = residentialAddress %} + + + {{ include('@ChillMain/Util/confirmation_template.html.twig', + { + 'title' : 'Delete residential address ?'|trans, + 'confirm_question' : 'Are you sure you want to remove this residential address for %name% ?'|trans({'%name%': person|chill_entity_render_string }), + 'cancel_route' : 'chill_person_residential_address_list', + 'cancel_parameters' : {'id' : person.Id}, + 'form' : delete_form + } ) }} + +
+{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/edit.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/edit.html.twig new file mode 100644 index 000000000..b84bd2543 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/edit.html.twig @@ -0,0 +1,51 @@ +{% extends "@ChillPerson/Person/layout.html.twig" %} + +{% set activeRouteKey = '' %} + +{% block title 'Edit a residential address'|trans %} + +{% block personcontent %} +
+ + {% block content %} +

{{ block('title') }}

+ + {{ form_start(form) }} + + {{ form_row(form.startDate) }} + {{ form_row(form.endDate) }} + + {% if residentialAddress.address is not null %} + + {% if form.address is defined %} + {{ form_row(form.address) }} + + {% block js %} + {{ encore_entry_script_tags('mod_input_address') }} + {% endblock %} + + {% block css %} + {{ encore_entry_link_tags('mod_input_address') }} + {% endblock %} + {% endif %} + {% endif %} + + {{ form_row(form.comment) }} + + + + {{ form_end(form) }} + + {% endblock %} + +
+{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/list.html.twig new file mode 100644 index 000000000..0eebf7e5d --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/list.html.twig @@ -0,0 +1,116 @@ +{% extends "@ChillPerson/Person/layout.html.twig" %} + +{% set activeRouteKey = '' %} + +{% block title %}{{ 'Residential addresses history for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}{% endblock %} + +{% block personcontent %} +
+ +

{{ 'Residential addresses history'|trans }}

+ + {% if is_granted('CHILL_PERSON_SEE', person) %} + + {% if addresses|length == 0 %} + {{ 'No address given'|trans }} + + {% else %} +
+ {% for a in addresses %} + + {% if a.address is not null %} + {% set kind = 'address' %} + {% else %} + {% set kind = null %} + {% endif %} + +
+
+ +
+
    + {% if a.endDate is not null %} +
  • {{'Since'|trans}} : {{ a.startDate|format_date('long') }}
  • + {% endif %} +
  • {{'Until'|trans}} : {{ a.endDate|format_date('long') }}
  • +
+
+
+
+
+
+ {% if is_granted('CHILL_PERSON_UPDATE', person) %} + + + {% endif %} +
+
    + {% if a.hostPerson is not null %} +
  • + + {{ "Address of"|trans}} + {{ a.hostPerson|chill_entity_render_box }} +
  • +
  • + {% set address_date = date(a.startDate|date("m/d/Y")) %} + {% if a.hostPerson.getCurrentHouseholdAddress(a.endDate) is not null %} + + {{ a.hostPerson.getCurrentHouseholdAddress(a.endDate)|chill_entity_render_box }} + {% endif %} +
  • + {% elseif a.hostThirdParty is not null %} +
  • + + {{ "Address of"|trans}} + {{ a.hostThirdParty|chill_entity_render_box }} +
  • +
  • + {% if a.hostThirdParty.address is not null %} + + {{ a.hostThirdParty.address|chill_entity_render_box }} + {% endif %} +
  • + {% else %} +
  • + {% if a.address is not null %} + + {{ a.address|chill_entity_render_box }} + {% endif %} + {% endif %} +
  • +
+
+ {% if not a.comment.isEmpty %} + {{ a.comment|chill_entity_render_box }} + {% endif %} +
+
+
+
+
+
+ + {% endfor %} +
+ {% endif %} + + + {% endif %} + + +
+{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/new.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/new.html.twig new file mode 100644 index 000000000..dd4b1cbe0 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/new.html.twig @@ -0,0 +1,29 @@ +{% extends "@ChillPerson/Person/layout.html.twig" %} + +{% set activeRouteKey = '' %} + +{% block title %}{{ 'New residential address'|trans }}{% endblock %} + +{% block personcontent %} +
+ + {% block content %} +

{{ block('title') }}

+ + {# TODO #} + {% block form %} + {% include '@ChillPerson/ResidentialAddress/_form.html.twig' %} + {% endblock %} + + {% endblock %} + +
+{% endblock %} + +{% block js %} + {{ encore_entry_script_tags('mod_pickentity_type') }} +{% endblock %} + +{% block css %} + {{ encore_entry_link_tags('mod_pickentity_type') }} +{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/new_pick_kind.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/new_pick_kind.html.twig new file mode 100644 index 000000000..3cc4af6c9 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/ResidentialAddress/new_pick_kind.html.twig @@ -0,0 +1,49 @@ +{% extends "@ChillMain/layout.html.twig" %} + +{% block title 'Which kind of residential address would you create ?'|trans %} + +{% block content %} +
+

{{ block('title') }}

+ +
+
+ +
+

{{ 'residential_address_person_explanation'|trans }}

+
+
+
+ +
+

{{ 'residential_address_third_party_explanation'|trans }}

+
+
+
+ +
+

{{ 'residential_address_new_address_explanation'|trans }}

+
+
+
+
+ +{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 2d6ff4c1e..37c5afb93 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -121,7 +121,6 @@ address_postcode_code: Code postal address_country_name: Pays address_country_code: Code pays - 'Alreay existing person': 'Dossiers déjà encodés' 'Add the person': 'Ajouter la personne' 'Add the person and create an accompanying period': "Créer la personne & créer une période d'accompagnement" @@ -243,6 +242,7 @@ Select a thirdparty: "Choisissez un tiers" # pickAPersonType Pick a person: Choisir une personne +# Address No address given: Pas d'adresse renseignée The address has been successfully updated: L'adresse a été mise à jour avec succès Update address for %name%: Mettre à jour une adresse pour %name% @@ -257,6 +257,31 @@ The new address was created successfully: La nouvelle adresse a été créée Add an address: Ajouter une adresse Back to the person details: Retour aux détails de la personne +# Residential address +Residential addresses history for %name%: Historique des adresses de résidence de %name% +Residential addresses history: Historique des adresses de résidence +Add a residential address: Ajouter une adresse de résidence +Which kind of residential address would you create ?: Quel type d'adresse de résidence voulez-vous créer? +The address of another person: L'adresse d'une autre personne +The address of a third party: L'adresse d'un tiers +A new address: Une nouvelle adresse +residential_address_person_explanation: L'adresse sera positionnée auprès d'un usager. Lorsque l'usager déménage, l'adresse de résidence suivra également cet usager +residential_address_third_party_explanation: L'adresse sera associée à celle d'un tiers. +residential_address_new_address_explanation: Créer une nouvelle adresse. L'adresse sera fixe. +New residential address: Nouvelle adresse de résidence +Host person: Choisir l'adresse d'un usager +Host third party: Choisir l'adresse d'un tiers +The new residential address was created successfully: La nouvelle adresse de résidence a été créée +Edit a residential address: Modifier l'addresse de résidence +The residential address was updated successfully: L'adresse de résidence a été mise à jour +Residential addresses: Adresses de résidence +Address of: Adresse de +Delete residential address: Supprimer l'adresse de résidence +Delete residential address ?: Supprimer l'adresse de résidence ? +Are you sure you want to remove this residential address for %name% ?: Êtes-vous sûr de vouloir supprimer l'adresse de résidence pour %name% ? +Residential address had been deleted: L'adresse de résidence a été supprimée + + #timeline Timeline: Historique Closing the accompanying period: Fermeture de la période d'accompagnement