From 34f22d237ed571f01cf18fbc1215a5ebd013a3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jul 2021 18:29:48 +0200 Subject: [PATCH 01/78] update schema to store location on accompanying period --- .../Entity/AccompanyingPeriod.php | 17 ++++++++ .../ChillPersonBundle/Entity/Person.php | 14 +++++++ .../migrations/Version20210727152826.php | 39 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20210727152826.php diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index b2de73651..41835e237 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -25,6 +25,7 @@ namespace Chill\PersonBundle\Entity; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Entity\Scope; +use Chill\MainBundle\Entity\Address; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWork; use Chill\PersonBundle\Entity\AccompanyingPeriod\ClosingMotive; use Chill\PersonBundle\Entity\AccompanyingPeriod\Comment; @@ -291,6 +292,22 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface */ private Collection $works; + /** + * @ORM\ManyToOne( + * targetEntity=Person::class, + * inversedBy="periodLocatedOn" + * ) + */ + private ?Person $personLocation = null; + + + /** + * @ORM\ManyToOne( + * targetEntity=Address::class + * ) + */ + private ?Address $addressLocation = null; + /** * AccompanyingPeriod constructor. * diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index 695970bfa..cf00eb9f1 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -30,6 +30,7 @@ use Chill\MainBundle\Entity\Country; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\MaritalStatus; +use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Household\HouseholdMember; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\Address; @@ -379,6 +380,19 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI */ private Collection $householdAddresses; + /** + * @ORM\OneToMany( + * targetEntity=AccompanyingPeriod::class, + * mappedBy="personLocation" + * ) + */ + private Collection $periodLocatedOn; + + /** + * Person constructor. + * + * @param \DateTime|null $opening + */ public function __construct() { $this->accompanyingPeriodParticipations = new ArrayCollection(); diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20210727152826.php b/src/Bundle/ChillPersonBundle/migrations/Version20210727152826.php new file mode 100644 index 000000000..f49c819d7 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20210727152826.php @@ -0,0 +1,39 @@ +addSql('ALTER TABLE chill_person_accompanying_period ADD personLocation_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_person_accompanying_period ADD addressLocation_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT FK_E260A868D5213D34 FOREIGN KEY (personLocation_id) REFERENCES chill_person_person (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE chill_person_accompanying_period ADD CONSTRAINT FK_E260A8689B07D6BF FOREIGN KEY (addressLocation_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_E260A868D5213D34 ON chill_person_accompanying_period (personLocation_id)'); + $this->addSql('CREATE INDEX IDX_E260A8689B07D6BF ON chill_person_accompanying_period (addressLocation_id)'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT FK_E260A868D5213D34'); + $this->addSql('ALTER TABLE chill_person_accompanying_period DROP CONSTRAINT FK_E260A8689B07D6BF'); + $this->addSql('DROP INDEX IDX_E260A868D5213D34'); + $this->addSql('DROP INDEX IDX_E260A8689B07D6BF'); + $this->addSql('ALTER TABLE chill_person_accompanying_period DROP personLocation_id'); + $this->addSql('ALTER TABLE chill_person_accompanying_period DROP addressLocation_id'); + } +} From 4cca148f69f6ca6b088d08faf6a1d6496f05ce13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Jul 2021 21:25:38 +0200 Subject: [PATCH 02/78] [AccompanyingPeriod] add location to serialization --- .../Entity/AccompanyingPeriod.php | 63 +++++++++++++++++++ .../ChillPersonBundle/chill.api.specs.yaml | 20 ++++++ 2 files changed, 83 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php index 41835e237..dda129296 100644 --- a/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php +++ b/src/Bundle/ChillPersonBundle/Entity/AccompanyingPeriod.php @@ -948,4 +948,67 @@ class AccompanyingPeriod implements TrackCreationInterface, TrackUpdateInterface return $this; } + + public function getAddressLocation(): ?Address + { + return $this->addressLocation; + } + + /** + * @Groups({"write"}) + */ + public function setAddressLocation(?Address $addressLocation = null): self + { + $this->addressLocation = $addressLocation; + + return $this; + } + + /** + * @Groups({"read"}) + */ + public function getPersonLocation(): ?Person + { + return $this->personLocation; + } + + /** + * @Groups({"write"}) + */ + public function setPersonLocation(?Person $person = null): self + { + $this->personLocation = $person; + + return $this; + } + + /** + * Get the location, taking precedence into account + * + * @Groups({"read"}) + */ + public function getLocation(\DateTimeImmutable $at = null): ?Address + { + if ($this->getPersonLocation() instanceof Person) { + return $this->getPersonLocation()->getCurrentHouseholdAddress($at); + } + + return $this->getAddressLocation(); + } + + /** + * Get where the location is + * + * @Groups({"read"}) + */ + public function getLocationStatus(): string + { + if ($this->getPersonLocation() instanceof Person) { + return 'person'; + } elseif ($this->getAddressLocation() instanceof Address) { + return 'address'; + } else { + return 'none'; + } + } } diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index 9fba308c5..71d5c119e 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -416,6 +416,26 @@ paths: This is my an initial comment. Say hello to the new "parcours"! + Setting person with id 8405 as locator: + value: + type: accompanying_period + id: 0 + personLocation: + type: person + id: 8405 + Removing person location for both person and address: + value: + type: accompanying_period + id: 0 + personLocation: null + addressLocation: null + Adding address with id 7960 as temporarily address: + value: + type: accompanying_period + id: 0 + personLocation: null + addressLocation: + id: 7960 responses: 401: description: "Unauthorized" From 4e8dd3b18902f420dc7e15d8ee05adf439c5b821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 28 Jul 2021 13:27:05 +0200 Subject: [PATCH 03/78] [AccompanyingPeriod] add flashbag message when located temporarily --- .../views/AccompanyingCourse/index.html.twig | 13 +++++++++++++ .../ChillPersonBundle/translations/messages.fr.yml | 1 + 2 files changed, 14 insertions(+) diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig index c15869b1d..5bab87ceb 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingCourse/index.html.twig @@ -59,6 +59,19 @@ + {% endif %} + + {% if accompanyingCourse.step != 'DRAFT' and + (accompanyingCourse.locationStatus == 'address' or accompanyingCourse.locationStatus == 'none') + %} +
+
+ {{ 'This course is located at a temporarily address. You should locate this course to an user'|trans }} +
+
+ + + {% endif %}

{{ 'Associated peoples'|trans }}

diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 32691bcb4..c081850db 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -339,6 +339,7 @@ Show Accompanying Course: Voir le parcours Edit Accompanying Course: Modifier le parcours Create Accompanying Course: Créer un nouveau parcours Drop Accompanying Course: Supprimer le parcours +This course is located at a temporarily address. You should locate this course to an user: Ce parcours est localisé à une adresse temporaire. Il devrait être localisé auprès d'un usager concerné. # Household Household: Ménage From 3c7b67604c8778d60bdcb26fd5120a59fe56ebd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 28 Jul 2021 14:46:03 +0200 Subject: [PATCH 04/78] [AccompanyingPeriod] create constraints for location --- .../AccompanyingPeriod/LocationValidity.php | 20 +++++++ .../LocationValidityValidator.php | 52 +++++++++++++++++++ .../ChillPersonBundle/config/services.yaml | 5 ++ .../ChillPersonBundle/config/validation.yaml | 1 + 4 files changed, 78 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php create mode 100644 src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidityValidator.php diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php new file mode 100644 index 000000000..9a64b3cf6 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php @@ -0,0 +1,20 @@ +render = $render; + } + + public function validate($period, Constraint $constraint) + { + if (!$constraint instanceof LocationValidity) { + throw new UnexpectedTypeException($constraint, LocationValidity::class); + } + + if (!$period instanceof AccompanyingPeriod) { + throw new UnexpectedValueException($value, AccompanyingPeriod::class); + } + + if ($period->getLocationStatus() === 'person') { + if (null === $period->getOpenParticipationContainsPerson( + $period->getPersonLocation())) { + $this->context->buildViolation($constraint->messagePersonLocatedMustBeAssociated) + ->setParameter('{{ person_name }}', $this->render->renderString( + $period->getPersonLocation(), [] + )) + ->addViolation() + ; + } + } + + if ($period->getStep() !== AccompanyingPeriod::STEP_DRAFT + && $period->getLocationStatus() === 'none') { + $this->context->buildViolation($constraint->messagePeriodMustRemainsLocated + ->addViolation() + ; + + } + + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services.yaml b/src/Bundle/ChillPersonBundle/config/services.yaml index a23ba39b3..c34f42ebb 100644 --- a/src/Bundle/ChillPersonBundle/config/services.yaml +++ b/src/Bundle/ChillPersonBundle/config/services.yaml @@ -85,3 +85,8 @@ services: resource: '../Templating/Entity' tags: - 'chill.render_entity' + + Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\: + autowire: true + autoconfigure: true + resource: '../Validator/Constraints/AccompanyingPeriod' diff --git a/src/Bundle/ChillPersonBundle/config/validation.yaml b/src/Bundle/ChillPersonBundle/config/validation.yaml index fb0dd7b50..23369a467 100644 --- a/src/Bundle/ChillPersonBundle/config/validation.yaml +++ b/src/Bundle/ChillPersonBundle/config/validation.yaml @@ -81,6 +81,7 @@ Chill\PersonBundle\Entity\AccompanyingPeriod: constraints: - Callback: callback: isDateConsistent + - 'Chill\PersonBundle\Validator\Constraints\AccompanyingPeriod\LocationValidity': ~ Chill\PersonBundle\Entity\PersonPhone: properties: From 3169da20ad3ebda91f7463c6c84023bdc9b71174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 28 Jul 2021 16:16:57 +0200 Subject: [PATCH 05/78] add test for accompanying period location validity --- .../LocationValidityValidatorTest.php | 122 ++++++++++++++++++ .../AccompanyingPeriod/LocationValidity.php | 2 +- .../LocationValidityValidator.php | 10 +- 3 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Validator/AccompanyingPeriod/LocationValidityValidatorTest.php diff --git a/src/Bundle/ChillPersonBundle/Tests/Validator/AccompanyingPeriod/LocationValidityValidatorTest.php b/src/Bundle/ChillPersonBundle/Tests/Validator/AccompanyingPeriod/LocationValidityValidatorTest.php new file mode 100644 index 000000000..b70a8146b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Validator/AccompanyingPeriod/LocationValidityValidatorTest.php @@ -0,0 +1,122 @@ +getConstraint(); + + $period = new AccompanyingPeriod(); + $person = new Person(); + $period->addPerson($person); + + $period->setPersonLocation($person); + + $this->validator->validate($period, $constraint); + + $this->assertNoViolation(); + } + + public function testPeriodDoesNotContainsPersonOnRemovedPerson() + { + $constraint = $this->getConstraint(); + + $period = new AccompanyingPeriod(); + $person1 = new Person(); + $period->addPerson($person1); + + $period->setPersonLocation($person1); + + $period->removePerson($person1); + + $this->validator->validate($period, $constraint); + + $this->buildViolation('messagePersonLocatedMustBeAssociated') + ->setParameters([ + '{{ person_name }}' => 'name' + ]) + ->assertRaised() + ; + } + + public function testPeriodDoesNotContainsPersonOnOtherPerson() + { + $constraint = $this->getConstraint(); + + $period = new AccompanyingPeriod(); + $person1 = new Person(); + $person2 = new Person(); + $period->addPerson($person1); + + $period->setPersonLocation($person2); + + $this->validator->validate($period, $constraint); + + $this->buildViolation('messagePersonLocatedMustBeAssociated') + ->setParameters([ + '{{ person_name }}' => 'name' + ]) + ->assertRaised() + ; + } + + public function testPeriodDoesNotContainsPersonOnAnyPerson() + { + $constraint = $this->getConstraint(); + + $period = new AccompanyingPeriod(); + $person1 = new Person(); + $period->setPersonLocation($person1); + + $this->validator->validate($period, $constraint); + + $this->buildViolation('messagePersonLocatedMustBeAssociated') + ->setParameters([ + '{{ person_name }}' => 'name' + ]) + ->assertRaised() + ; + } + + public function testRemoveLocationOnPeriodValidated() + { + $constraint = $this->getConstraint(); + + $period = new AccompanyingPeriod(); + $period->setStep('not draft'); + + $this->validator->validate($period, $constraint); + + $this->buildViolation('messagePeriodMustRemainsLocated') + ->assertRaised() + ; + } + + protected function getConstraint() + { + return new LocationValidity([ + 'messagePersonLocatedMustBeAssociated' => 'messagePersonLocatedMustBeAssociated', + 'messagePeriodMustRemainsLocated' => 'messagePeriodMustRemainsLocated' + ]); + } + + protected function createValidator() + { + $render= $this->createMock(PersonRender::class); + $render->method('renderString') + ->willReturn('name') + ; + + return new LocationValidityValidator($render); + } + +} diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php index 9a64b3cf6..75c10ca75 100644 --- a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidity.php @@ -11,7 +11,7 @@ class LocationValidity extends Constraint { public $messagePersonLocatedMustBeAssociated = "The person where the course is located must be associated to the course. Change course's location before removing the person."; - public $messagPeriodMustRemainsLocated = "The period must remains located"; + public $messagePeriodMustRemainsLocated = "The period must remains located"; public function getTargets() { diff --git a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidityValidator.php b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidityValidator.php index 3a0b1a3b3..a92120f2d 100644 --- a/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidityValidator.php +++ b/src/Bundle/ChillPersonBundle/Validator/Constraints/AccompanyingPeriod/LocationValidityValidator.php @@ -42,10 +42,12 @@ class LocationValidityValidator extends ConstraintValidator if ($period->getStep() !== AccompanyingPeriod::STEP_DRAFT && $period->getLocationStatus() === 'none') { - $this->context->buildViolation($constraint->messagePeriodMustRemainsLocated - ->addViolation() - ; - + $this->context + ->buildViolation( + $constraint->messagePeriodMustRemainsLocated + ) + ->addViolation() + ; } } From 5ef5b65d90dc7d73c2b4a58d6a9986f6104cdfe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jul 2021 12:24:22 +0200 Subject: [PATCH 06/78] Add address suggestion for a person --- .../Controller/PersonApiController.php | 38 +++++++++++++++++++ .../Controller/PersonApiControllerTest.php | 27 +++++++++++++ .../ChillPersonBundle/chill.api.specs.yaml | 29 +++++++++++++- 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php b/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php index 9db1854fc..62b61a942 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php @@ -18,12 +18,15 @@ namespace Chill\PersonBundle\Controller; use Chill\PersonBundle\Security\Authorization\PersonVoter; +use Chill\PersonBundle\Entity\Person; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Symfony\Component\Security\Core\Role\Role; use Chill\MainBundle\CRUD\Controller\ApiController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Chill\MainBundle\Entity\Address; +use Symfony\Component\Routing\Annotation\Route; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; class PersonApiController extends ApiController { @@ -54,4 +57,39 @@ class PersonApiController extends ApiController return $this->addRemoveSomething('address', $id, $request, $_format, 'address', Address::class, [ 'groups' => [ 'read' ] ]); } + /** + * @Route("/api/1.0/person/address/suggest/by-person/{person_id}.{_format}", + * name="chill_person_address_suggest_by_person", + * requirements={ + * "_format"="json" + * } + * ) + * @ParamConverter("person", options={"id" = "person_id"}) + */ + public function suggestAddress(Person $person, Request $request, string $_format): Response + { + $this->denyAccessUnlessGranted(PersonVoter::SEE, $person); + + $addresses = []; + // collect addresses from location in courses + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (null !== $participation->getAccompanyingPeriod()->getAddressLocation()) { + $a = $participation->getAccompanyingPeriod()->getAddressLocation(); + $addresses[$a->getId()] = $a; + } + if (null !== $participation->getAccompanyingPeriod()->getPersonLocation()) { + $a = $participation->getAccompanyingPeriod()->getAddressLocation(); + $addresses[$a->getId()] = $a; + } + } + + \array_unique($addresses); + // remove the actual address + $actual = $person->getCurrentHouseholdAddress(); + if (null !== $actual) { + $addresses = \array_filter($addresses, fn($a) => $a !== $actual); + } + + return $this->json(\array_values($addresses), Response::HTTP_OK, [], [ 'groups' => [ 'read' ]]); + } } diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonApiControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonApiControllerTest.php index d261f4294..23890cdb9 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/PersonApiControllerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/PersonApiControllerTest.php @@ -45,6 +45,31 @@ class PersonApiControllerTest extends WebTestCase $this->assertEquals($personId, $data['id']); } + /** + * @dataProvider dataGetPersonFromCenterA + */ + public function testPersonAddressSuggestion($personId): void + { + $client = $this->getClientAuthenticated(); + + $client->request(Request::METHOD_GET, "/api/1.0/person/address/suggest/by-person/{$personId}.json"); + + $this->assertResponseIsSuccessful(); + } + + /** + * @dataProvider dataGetPersonFromCenterB + */ + public function testPersonAddressSuggestionUnauthorized($personId): void + { + $client = $this->getClientAuthenticated(); + + $client->request(Request::METHOD_GET, "/api/1.0/person/address/suggest/by-person/{$personId}.json"); + $response = $client->getResponse(); + + $this->assertEquals(403, $response->getStatusCode()); + } + public function dataGetPersonFromCenterA(): \Iterator { self::bootKernel(); @@ -61,6 +86,8 @@ class PersonApiControllerTest extends WebTestCase yield \array_pop($personIds); yield \array_pop($personIds); + yield \array_pop($personIds); + yield \array_pop($personIds); } public function dataGetPersonFromCenterB(): \Iterator diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index 71d5c119e..e89088c86 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -354,10 +354,35 @@ paths: description: "OK" 422: description: "Unprocessable entity (validation errors)" - 400: - description: "transition cannot be applyed" + /1.0/person/address/suggest/by-person/{id}.json: + get: + tags: + - address + summary: get a list of suggested address for a person + description: > + The address are computed from various source. Currently: + + - the address of course to which the person is participating + + The current person's address is always ignored. + parameters: + - name: id + in: path + required: true + description: The person id + schema: + type: integer + format: integer + minimum: 1 + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" /1.0/person/accompanying-course/{id}.json: get: From 886924a7e5cb2f61b37114b88c89d97cda0f515a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 29 Jul 2021 16:01:17 +0200 Subject: [PATCH 07/78] add address suggestion by household --- .../Controller/HouseholdApiController.php | 43 +++++++++++++++++ .../Controller/PersonApiController.php | 10 ++-- .../Controller/HouseholdApiControllerTest.php | 46 ++++++++++++++++++- .../ChillPersonBundle/chill.api.specs.yaml | 28 +++++++++++ 4 files changed, 122 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdApiController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdApiController.php index 1e15490dc..0bb804689 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdApiController.php @@ -6,10 +6,12 @@ use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\Entity\Address; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Entity\Person; +use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Repository\Household\HouseholdRepository; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; +use Symfony\Component\Routing\Annotation\Route; class HouseholdApiController extends ApiController { @@ -50,4 +52,45 @@ class HouseholdApiController extends ApiController return $this->json($collection, Response::HTTP_OK, [], [ "groups" => ["read"]]); } + + /** + * @Route("/api/1.0/person/address/suggest/by-household/{household_id}.{_format}", + * name="chill_person_address_suggest_by_household", + * requirements={ + * "_format"="json" + * } + * ) + * @ParamConverter("household", options={"id" = "household_id"}) + */ + public function suggestAddressByHousehold(Household $household, string $_format) + { + // TODO add acl + + $addresses = []; + // collect addresses from location in courses + foreach ($household->getCurrentPersons() as $person) { + foreach ($person->getAccompanyingPeriodParticipations() as $participation) { + if (null !== $participation->getAccompanyingPeriod()->getAddressLocation()) { + $a = $participation->getAccompanyingPeriod()->getAddressLocation(); + $addresses[$a->getId()] = $a; + } + if (null !== $personLocation = $participation + ->getAccompanyingPeriod()->getPersonLocation()) { + $a = $personLocation->getCurrentHouseholdAddress(); + if (null !== $a) { + $addresses[$a->getId()] = $a; + } + } + } + } + + // remove the actual address + $actual = $household->getCurrentAddress(); + if (null !== $actual) { + $addresses = \array_filter($addresses, fn($a) => $a !== $actual); + } + + return $this->json(\array_values($addresses), Response::HTTP_OK, [], + [ 'groups' => [ 'read' ] ]); + } } diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php b/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php index 62b61a942..b3f4087eb 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonApiController.php @@ -77,13 +77,15 @@ class PersonApiController extends ApiController $a = $participation->getAccompanyingPeriod()->getAddressLocation(); $addresses[$a->getId()] = $a; } - if (null !== $participation->getAccompanyingPeriod()->getPersonLocation()) { - $a = $participation->getAccompanyingPeriod()->getAddressLocation(); - $addresses[$a->getId()] = $a; + if (null !== $personLocation = $participation + ->getAccompanyingPeriod()->getPersonLocation()) { + $a = $personLocation->getCurrentHouseholdAddress(); + if (null !== $a) { + $addresses[$a->getId()] = $a; + } } } - \array_unique($addresses); // remove the actual address $actual = $person->getCurrentHouseholdAddress(); if (null !== $actual) { diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdApiControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdApiControllerTest.php index f6adc5d01..273824782 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdApiControllerTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdApiControllerTest.php @@ -4,6 +4,7 @@ namespace Chill\PersonBundle\Tests\Controller; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\MainBundle\Test\PrepareClientTrait; +use Chill\PersonBundle\Entity\Household\Household; use Symfony\Component\HttpFoundation\Request; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; @@ -29,6 +30,21 @@ class HouseholdApiControllerTest extends WebTestCase $this->assertResponseIsSuccessful(); } + /** + * @dataProvider generateHouseholdId + */ + public function testSuggestAddressByHousehold(int $householdId) + { + $client = $this->getClientAuthenticated(); + + $client->request( + Request::METHOD_GET, + "/api/1.0/person/address/suggest/by-household/{$householdId}.json" + ); + + $this->assertResponseIsSuccessful(); + } + public function generatePersonId() { self::bootKernel(); @@ -51,5 +67,33 @@ class HouseholdApiControllerTest extends WebTestCase ->first()->getPerson(); yield [ $person->getId() ]; - } + } + + public function generateHouseholdId() + { + self::bootKernel(); + + $qb = self::$container->get(EntityManagerInterface::class) + ->createQueryBuilder(); + + $householdIds = $qb + ->select('DISTINCT household.id') + ->from(Household::class, 'household') + ->join('household.members', 'members') + ->join('members.person', 'person') + ->join('person.center', 'center') + ->where($qb->expr()->eq('center.name', ':center_name')) + ->andWhere($qb->expr()->gt('SIZE(person.accompanyingPeriodParticipations)', 0)) + ->setParameter('center_name', 'Center A') + ->setMaxResults(100) + ->getQuery() + ->getResult() + ; + + \shuffle($householdIds); + + yield [ \array_pop($householdIds)['id'] ]; + yield [ \array_pop($householdIds)['id'] ]; + yield [ \array_pop($householdIds)['id'] ]; + } } diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index e89088c86..0684a352c 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -384,6 +384,34 @@ paths: 200: description: "OK" + /1.0/person/address/suggest/by-household/{id}.json: + get: + tags: + - address + summary: get a list of suggested address for a household + description: > + The address are computed from various source. Currently: + + - the address of course to which the members is participating + + The current household address is always ignored. + parameters: + - name: id + in: path + required: true + description: The household id + schema: + type: integer + format: integer + minimum: 1 + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" + /1.0/person/accompanying-course/{id}.json: get: tags: From d916b575da22a9b9ca13b4d6923882ff663c7ed1 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Mon, 2 Aug 2021 13:26:23 +0200 Subject: [PATCH 08/78] AddAddress modal: make title dynamically passed by parent --- .../Resources/public/vuejs/Address/App.vue | 8 +++-- .../vuejs/Address/components/AddAddress.vue | 32 ++++++++++--------- .../public/vuejs/HouseholdAddress/App.vue | 6 ++-- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue index dea280212..c1d6fa5ac 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue @@ -4,6 +4,8 @@

{{ $t('create_a_new_address') }}

{{ $t('edit_a_new_address') }}

@@ -14,10 +16,10 @@ - +

{{ $t('date') }}

- +
- +
{{ errors }}
diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue index 2fb5cf6c5..13f767fe0 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue @@ -1,9 +1,9 @@ + + diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig index 5f5a4a888..1868bd9de 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Address/edit.html.twig @@ -18,15 +18,15 @@ {% set activeRouteKey = '' %} -{% block title 'Modify address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) %} +{% block title 'Edit an address'|trans %} {% block personcontent %} -
- - {% block content %} -

{{ block('title') }}

-
- {% endblock %} +
+ + {% block content %} +

{{ block('title') }}

+
+ {% endblock %}
{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig index 2365c2d03..cd45d66ea 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Address/new.html.twig @@ -18,16 +18,16 @@ {% set activeRouteKey = '' %} -{% block title %}{{ 'New address for %name%'|trans({ '%name%': person.firstName|capitalize ~ ' ' ~ person.lastName } )|capitalize }}{% endblock %} +{% block title %}{{ 'New address'|trans }}{% endblock %} {% block personcontent %}
- {% block content %} -

{{ block('title') }}

-
- {% endblock %} - + {% block content %} +

{{ block('title') }}

+
+ {% endblock %} +
{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/chill.webpack.config.js b/src/Bundle/ChillPersonBundle/chill.webpack.config.js index ebfdef01d..1b779cb79 100644 --- a/src/Bundle/ChillPersonBundle/chill.webpack.config.js +++ b/src/Bundle/ChillPersonBundle/chill.webpack.config.js @@ -8,11 +8,11 @@ module.exports = function(encore, entries) ChillPersonAssets: __dirname + '/Resources/public' }); - encore.addEntry('vue_household_address', __dirname + '/Resources/public/vuejs/HouseholdAddress/index.js'); - encore.addEntry('vue_household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js'); + //encore.addEntry('vue_household_address', __dirname + '/Resources/public/vuejs/HouseholdAddress/index.js'); + //encore.addEntry('vue_household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js'); encore.addEntry('vue_accourse', __dirname + '/Resources/public/vuejs/AccompanyingCourse/index.js'); - encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js'); - encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js'); + //encore.addEntry('vue_accourse_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js'); + //encore.addEntry('vue_accourse_work_edit', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js'); encore.addEntry('page_household_edit_metadata', __dirname + '/Resources/public/page/household_edit_metadata/index.js'); encore.addEntry('page_person', __dirname + '/Resources/public/page/person/index.js'); diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index 65e1bb6bd..d030d9dc8 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -207,8 +207,10 @@ 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% Modify address for %name%: Modifier une adresse pour %name% +Edit an address: Modifier une adresse Addresses history for %name%: Historique des adresses de %name% Addresses history: Historique des adresses +New address : Nouvelle adresse New address for %name% : Nouvelle adresse pour %name% The new address was created successfully: La nouvelle adresse a été créée Add an address: Ajouter une adresse From 01cc2301367f0d835445b5dad5223d0d2b378d85 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 5 Aug 2021 22:04:41 +0200 Subject: [PATCH 16/78] Submitting address, and validFrom field --- .../Resources/public/vuejs/Address/App.vue | 29 +++--- .../vuejs/Address/components/AddAddress.vue | 75 +++++++++++---- .../vuejs/Address/components/ShowAddress.vue | 95 ++++++++++++------- 3 files changed, 134 insertions(+), 65 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue index a820c253d..efe444075 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue @@ -1,10 +1,19 @@ @@ -24,10 +33,8 @@ export default { personId: window.personId, addressId: window.addressId, backUrl: `/fr/person/${window.personId}/address/list`, //TODO better way to pass this - validFrom: new Date().toISOString().split('T')[0] }, addAddress: { - key: 'person', options: { /// Options override default @@ -39,19 +46,15 @@ export default { /// Display each step in page or Modal //bindModal: { step1: false, step2: false } //TODO true-false must not be possible - } + }, + type: 'person', + result: null // <== returned from addAddress component } } }, methods: { - submitAddress({ submited, flag }) { - console.log('@@@ CLICK button submitAddress'); - - console.log('address to post:', submited); - console.log('datas by refs: ', this.$refs.addAddress.entity.address.text); - - this.$refs.addAddress.initForm(); // to cast child method - flag.showPane = false; + displayErrors() { + return this.$refs.addAddress.errorMsg; } } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue index fc38f630b..0199dff4d 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue @@ -26,7 +26,8 @@ v-bind:options="this.options" v-bind:default="this.default" v-bind:entity="this.entity" - v-bind:flag="this.flag"> + v-bind:flag="this.flag" + ref="showAddress"> @@ -36,7 +37,7 @@ {{ $t('action.edit')}} @@ -51,8 +52,9 @@ v-bind:default="this.default" v-bind:entity="this.entity" v-bind:flag="this.flag" + ref="showAddress" v-bind:insideModal="false" @openEditPane="openEditPane" - @submitAddress="$emit('submitAddress', { getSubmited , flag })"> + @submitAddress="submitAddress">
@@ -122,8 +124,7 @@ import { export default { name: "AddAddress", - props: ['context', 'options'], - emits: ['submitAddress'], + props: ['context', 'options', 'result'], components: { Modal, ShowAddress, @@ -173,6 +174,10 @@ export default { zoom: 12 }, }, + valid: { + from: null, + to: null + }, errorMsg: [] } }, @@ -197,11 +202,8 @@ export default { return (this.context.edit) ? this.options.title.edit : this.options.title.create; } return (this.context.edit) ? this.default.title.edit : this.default.title.create; - }, - - getSubmited() { - return this.entity.address; } + }, mounted() { if (!this.step1WithModal) { @@ -221,11 +223,13 @@ export default { } this.flag.showPane = true; }, + openEditPane() { console.log('open the Edit panel'); this.initForm(); this.getCountries(); }, + closeEditPane() { console.log('close the Edit Panel (with validation)'); this.applyChanges(); @@ -373,7 +377,6 @@ export default { * then update existing address with backend datas when promise is resolved */ updateAddress(payload) { - console.log('updateAddress payload', payload); // TODO change the condition because it writes new postal code in edit mode now: !writeNewPostalCode this.flag.loading = true; @@ -387,7 +390,6 @@ export default { body.postcode = {'id': postalCode.id }, patchAddress(payload.addressId, body) .then(address => new Promise((resolve, reject) => { - console.log('update address'); this.entity.address = address; this.flag.loading = false; resolve(); @@ -401,7 +403,6 @@ export default { } else { patchAddress(payload.addressId, payload.newAddress) .then(address => new Promise((resolve, reject) => { - console.log('update address'); this.entity.address = address; this.flag.loading = false; resolve(); @@ -418,7 +419,6 @@ export default { * creating new address, and receive backend datas when promise is resolved */ addAddress(payload) { - console.log('addAddress payload', payload); this.flag.loading = true; if('newPostcode' in payload){ @@ -431,7 +431,6 @@ export default { body.postcode = {'id': postalCode.id}, postAddress(body) .then(address => new Promise((resolve, reject) => { - console.log('add address'); this.entity.address = address; resolve(); this.flag.loading = false; @@ -445,7 +444,6 @@ export default { } else { postAddress(payload) .then(address => new Promise((resolve, reject) => { - console.log('add address'); this.entity.address = address; resolve(); this.flag.loading = false; @@ -455,9 +453,52 @@ export default { this.flag.loading = false; }); } + }, + + /* + * When submited + */ + submitAddress() { + console.log('@@@ CLICK button submitAddress'); + this.addDateToAddressAndAddressToPerson({ + personId: this.context.personId, + addressId: this.entity.address.address_id, + body: { validFrom: { datetime: `${this.$refs.showAddress.validFrom}T00:00:00+0100`}}, + backUrl: this.context.backUrl + }); + this.initForm(); + this.flag.showPane = false; + }, + + addDateToAddressAndAddressToPerson(payload) { + console.log('addDateToAddressAndAddressToPerson payload', payload); + this.flag.loading = true; + patchAddress(payload.addressId, payload.body) + .then(address => new Promise((resolve, reject) => { + this.valid.from = address.validFrom; + resolve(); + }).then( + postAddressToPerson(payload.personId, payload.addressId) + .then(person => new Promise((resolve, reject) => { + + console.log('commit addAddressToPerson !!!', person); + this.result = person; + + this.flag.loading = false; + this.flag.success = true; + window.location.assign(payload.backUrl); + resolve(); + })) + .catch((error) => { + this.errorMsg.push(error); + this.flag.loading = false; + }) + )) + .catch((error) => { + this.errorMsg.push(error); + this.flag.loading = false; + }); } - - } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue index c59104aca..e19c4f333 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue @@ -20,41 +20,63 @@ {{ address.country.name.fr }}

+
+
+ + {{ $t('floor') }}: {{ address.floor }} + +
+
+ + {{ $t('corridor') }}: {{ address.corridor }} + +
+
+ + {{ $t('steps') }}: {{ address.steps }} + +
+
+ + {{ $t('flat') }}: {{ address.flat }} + +
+
+ + {{ $t('buildingName') }}: {{ address.buildingName }} + +
+
+ + {{ $t('extra') }}: {{ address.extra }} + +
+
+ + {{ $t('distribution') }}: {{ address.distribution }} + +
+
-
- - {{ $t('floor') }}: {{ address.floor }} - -
-
- - {{ $t('corridor') }}: {{ address.corridor }} - -
-
- - {{ $t('steps') }}: {{ address.steps }} - -
-
- - {{ $t('flat') }}: {{ address.flat }} - -
-
- - {{ $t('buildingName') }}: {{ address.buildingName }} - -
-
- - {{ $t('extra') }}: {{ address.extra }} - -
-
- - {{ $t('distribution') }}: {{ address.distribution }} - +
+

{{ $t('date') }}

+
+ + +
+ +
+ {{ $t('loading') }} +
+
+ {{ $t('person_address_creation_success') }} +
@@ -93,7 +115,7 @@ export default { 'errorMsg', 'insideModal' ], - emits: ['openEditPane', 'submitAddress'], + emits: ['openEditPane', 'submitAddress', 'validFrom'], computed: { address() { return this.entity.address; @@ -109,6 +131,9 @@ export default { }, getSubmited() { return this.entity.address; + }, + validFrom() { + return new Date().toISOString().split('T')[0]; } } }; From 9f3ceb94f08851470a29bb21c5437a7d69eb982a Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Fri, 6 Aug 2021 15:53:50 +0200 Subject: [PATCH 17/78] adding options to custom button, and improve stepWithModal options --- .../Resources/public/vuejs/Address/App.vue | 17 ++++--- .../vuejs/Address/components/AddAddress.vue | 49 +++++++++++++------ .../translations/messages.fr.yml | 1 + 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue index efe444075..a2eec127d 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue @@ -4,11 +4,6 @@ class="alert alert-danger my-2"> {{ error }} - -
-      {{ addAddress.result.address_id }}
-   
- - {{ $t(getTextButton) }} + class="btn mt-4" :class="getClassButton" + type="button" name="button" :title="$t(getTextButton)"> + {{ $t(getTextButton) }} + + Date: Fri, 6 Aug 2021 16:25:04 +0200 Subject: [PATCH 18/78] when creating new address, start first with edit panel --- .../public/vuejs/Address/components/AddAddress.vue | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue index b4fc037a1..f543bccc1 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue @@ -203,7 +203,6 @@ export default { } return step2; }, - getTextTitle() { if (this.options.title) { return (this.context.edit) ? this.options.title.edit : this.options.title.create; @@ -242,7 +241,16 @@ export default { if (this.context.addressId) { this.getInitialAddress(this.context.addressId); } - this.flag.showPane = true; + // when create new address, start first with editPane + if ( this.context.edit === false + && this.flag.editPane === false + ) { + this.openEditPane(); + this.flag.editPane = true; + + } else { + this.flag.showPane = true; + } }, openEditPane() { From b62597426c3a2e0146cd1e58976d829f1e41b22d Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Fri, 6 Aug 2021 16:30:48 +0200 Subject: [PATCH 19/78] classes for address-valid --- .../Resources/public/chill/scss/render_box.scss | 4 ++-- .../Resources/public/vuejs/Address/components/ShowAddress.vue | 4 ++-- .../ChillMainBundle/Resources/views/Entity/address.html.twig | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss index 68bbe2afc..cd57ba3cd 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss +++ b/src/Bundle/ChillMainBundle/Resources/public/chill/scss/render_box.scss @@ -94,8 +94,8 @@ section.chill-entity { } span.address-valid { - &.address-since {} - &.address-until {} + &.date-since {} + &.date-until {} } } diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue index e19c4f333..07e4617d3 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/ShowAddress.vue @@ -58,8 +58,8 @@ -
-

{{ $t('date') }}

+
+

{{ $t('date') }}

+ {{ 'Since %date%'|trans( { '%date%' : address.validFrom|format_date('long') } ) }} {%- endif -%} {%- if options['with_valid_to'] == true -%} - + {{ 'Until %date%'|trans( { '%date%' : address.validTo|format_date('long') } ) }} {%- endif -%} From da09e10fb1c2b5e06e115324d4b7086d2ea29afb Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Fri, 6 Aug 2021 17:36:19 +0200 Subject: [PATCH 20/78] adding options in root component to see result or redirect (not working) --- .../Resources/public/vuejs/Address/App.vue | 28 +++++++++++++++---- .../vuejs/Address/components/AddAddress.vue | 7 +++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue index a2eec127d..fa7bd5e95 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/App.vue @@ -1,9 +1,23 @@ diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js index 1622b4ff3..68c23966c 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/js/i18n.js @@ -65,8 +65,8 @@ const appMessages = { }, courselocation: { title: "Localisation du parcours", - add_temp_address: "Ajouter une adresse temporaire", - edit_temp_address: "Modifier l'adresse temporaire", + add_temporary_address: "Ajouter une adresse temporaire", + edit_temporary_address: "Modifier l'adresse temporaire", assign_course_address: "Désigner comme l'adresse du parcours", }, referrer: { diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js index e377b358a..b62967616 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/store/index.js @@ -1,9 +1,9 @@ import 'es6-promise/auto'; import { createStore } from 'vuex'; -import { getAccompanyingCourse, +import { getAccompanyingCourse, patchAccompanyingCourse, confirmAccompanyingCourse, - postParticipation, + postParticipation, postRequestor, postResource, postSocialIssue } from '../api'; @@ -13,20 +13,21 @@ const id = window.accompanyingCourseId; let initPromise = getAccompanyingCourse(id) .then(accompanying_course => new Promise((resolve, reject) => { - + const store = createStore({ strict: debug, modules: { }, state: { accompanyingCourse: accompanying_course, + addressContext: {}, errorMsg: [] }, getters: { }, mutations: { catchError(state, error) { - state.errorMsg.push(error); + state.errorMsg.push(error); }, removeParticipation(state, participation) { //console.log('### mutation: remove participation', participation.id); @@ -77,7 +78,7 @@ let initPromise = getAccompanyingCourse(id) postFirstComment(state, comment) { //console.log('### mutation: postFirstComment', comment); state.accompanyingCourse.initialComment = comment; - }, + }, updateSocialIssues(state, value) { state.accompanyingCourse.socialIssues = value; }, @@ -92,6 +93,10 @@ let initPromise = getAccompanyingCourse(id) confirmAccompanyingCourse(state, response) { //console.log('### mutation: confirmAccompanyingCourse: response', response); state.accompanyingCourse.step = response.step; + }, + setAddressContext(state, context) { + //console.log('define location context'); + state.addressContext = context; } }, actions: { @@ -105,7 +110,7 @@ let initPromise = getAccompanyingCourse(id) .then(participation => new Promise((resolve, reject) => { commit('closeParticipation', { participation, payload }); resolve(); - })).catch((error) => { commit('catchError', error) }); + })).catch((error) => { commit('catchError', error) }); }, addParticipation({ commit }, payload) { //console.log('## action: fetch post participation (select item): payload', payload); @@ -113,7 +118,7 @@ let initPromise = getAccompanyingCourse(id) .then(participation => new Promise((resolve, reject) => { commit('addParticipation', participation); resolve(); - })).catch((error) => { commit('catchError', error) }); + })).catch((error) => { commit('catchError', error) }); }, removeRequestor({ commit, dispatch }) { //console.log('## action: fetch delete requestor'); @@ -122,7 +127,7 @@ let initPromise = getAccompanyingCourse(id) commit('removeRequestor'); dispatch('requestorIsAnonymous', false); resolve(); - })).catch((error) => { commit('catchError', error) }); + })).catch((error) => { commit('catchError', error) }); }, addRequestor({ commit }, payload) { //console.log('## action: fetch post requestor: payload', payload); @@ -130,7 +135,7 @@ let initPromise = getAccompanyingCourse(id) .then(requestor => new Promise((resolve, reject) => { commit('addRequestor', requestor); resolve(); - })).catch((error) => { commit('catchError', error) }); + })).catch((error) => { commit('catchError', error) }); }, requestorIsAnonymous({ commit }, payload) { //console.log('## action: fetch patch AccompanyingCourse: payload', payload); From c302452e01b20fd284b288350e07c5ee1261c617 Mon Sep 17 00:00:00 2001 From: Mathieu Jaumotte Date: Thu, 12 Aug 2021 16:14:17 +0200 Subject: [PATCH 47/78] improve Address reusability: move i18n translations out of root component --- .../public/vuejs/Address/components/AddAddress.vue | 11 ++++++++--- .../Resources/public/vuejs/Address/index.js | 4 ---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue index 13d3cc150..c3921a609 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue @@ -15,7 +15,7 @@ @close="flag.showPane = false">