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] 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: