mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
PersonAddressMoveEvent on household move (wip)
This commit is contained in:
parent
8675bb65c1
commit
caa63ea97a
@ -918,15 +918,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Controller/AccompanyingPeriodController.php
|
||||
|
||||
-
|
||||
message:
|
||||
"""
|
||||
#^Parameter \\$translator of method Chill\\\\PersonBundle\\\\Controller\\\\HouseholdController\\:\\:__construct\\(\\) has typehint with deprecated interface Symfony\\\\Component\\\\Translation\\\\TranslatorInterface\\:
|
||||
since Symfony 4\\.2, use Symfony\\\\Contracts\\\\Translation\\\\TranslatorInterface instead$#
|
||||
"""
|
||||
count: 1
|
||||
path: src/Bundle/ChillPersonBundle/Controller/HouseholdController.php
|
||||
|
||||
-
|
||||
message:
|
||||
"""
|
||||
|
@ -142,7 +142,7 @@ class Address
|
||||
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\PostalCode")
|
||||
* @Groups({"write"})
|
||||
*/
|
||||
private ?PostalCode $postcode;
|
||||
private ?PostalCode $postcode = null;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
@ -305,9 +305,8 @@ class Address
|
||||
/**
|
||||
* Get postcode.
|
||||
*
|
||||
* @return PostalCode
|
||||
*/
|
||||
public function getPostcode()
|
||||
public function getPostcode(): ?PostalCode
|
||||
{
|
||||
return $this->postcode;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\AccompanyingPeriod\Events;
|
||||
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\Notification;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
|
||||
@ -78,7 +79,7 @@ class PersonMoveEventSubscriber implements EventSubscriberInterface
|
||||
) {
|
||||
// reset the location, back to an address
|
||||
$period->setPersonLocation(null);
|
||||
$period->setAddressLocation($event->getPreviousAddress());
|
||||
$period->setAddressLocation(Address::createFromAddress($event->getPreviousAddress()));
|
||||
|
||||
$notification = new Notification();
|
||||
$notification
|
||||
|
@ -16,15 +16,20 @@ use Chill\MainBundle\Entity\Address;
|
||||
use Chill\MainBundle\Entity\AddressReference;
|
||||
use Chill\MainBundle\Serializer\Model\Collection;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdMember;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Event\Person\PersonAddressMoveEvent;
|
||||
use Chill\PersonBundle\Repository\Household\HouseholdACLAwareRepositoryInterface;
|
||||
use Chill\PersonBundle\Repository\Household\HouseholdRepository;
|
||||
use Chill\PersonBundle\Security\Authorization\HouseholdVoter;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
|
||||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
||||
use function array_filter;
|
||||
use function array_values;
|
||||
|
||||
@ -34,10 +39,14 @@ class HouseholdApiController extends ApiController
|
||||
|
||||
private HouseholdRepository $householdRepository;
|
||||
|
||||
private EventDispatcherInterface $eventDispatcher;
|
||||
|
||||
public function __construct(
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
HouseholdRepository $householdRepository,
|
||||
HouseholdACLAwareRepositoryInterface $householdACLAwareRepository
|
||||
) {
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->householdRepository = $householdRepository;
|
||||
$this->householdACLAwareRepository = $householdACLAwareRepository;
|
||||
}
|
||||
@ -66,9 +75,51 @@ class HouseholdApiController extends ApiController
|
||||
]);
|
||||
}
|
||||
|
||||
public function householdAddressApi($id, Request $request, string $_format): Response
|
||||
/**
|
||||
* Add an address to a household
|
||||
*
|
||||
* @Route("/api/1.0/person/household/{id}/address.{_format}", name="chill_api_single_household_address",
|
||||
* methods={"POST"}, requirements={"_format": "json"})
|
||||
*/
|
||||
public function householdAddressApi(Household $household, Request $request, string $_format): Response
|
||||
{
|
||||
return $this->addRemoveSomething('address', $id, $request, $_format, 'address', Address::class, ['groups' => ['read']]);
|
||||
$this->denyAccessUnlessGranted(HouseholdVoter::EDIT, $household);
|
||||
|
||||
/** @var Address $address */
|
||||
$address = $this->getSerializer()->deserialize($request->getContent(), Address::class, $_format, [
|
||||
AbstractNormalizer::GROUPS => ['write']
|
||||
]);
|
||||
|
||||
$household->addAddress($address);
|
||||
|
||||
foreach ($household->getMembersOnRange(
|
||||
\DateTimeImmutable::createFromMutable($address->getValidFrom()),
|
||||
null === $address->getValidTo() ? null :
|
||||
\DateTimeImmutable::createFromMutable($address->getValidTo())
|
||||
) as $member) {
|
||||
/** @var HouseholdMember $member */
|
||||
$event = new PersonAddressMoveEvent($member->getPerson());
|
||||
$event
|
||||
->setPreviousAddress($household->getPreviousAddressOf($address))
|
||||
->setNextAddress($address)
|
||||
;
|
||||
$this->eventDispatcher->dispatch($event);
|
||||
}
|
||||
|
||||
$errors = $this->getValidator()->validate($household);
|
||||
|
||||
if ($errors->count() > 0) {
|
||||
return $this->json($errors, 422);
|
||||
}
|
||||
|
||||
$this->getDoctrine()->getManager()->flush();
|
||||
|
||||
return $this->json(
|
||||
$address,
|
||||
Response::HTTP_OK,
|
||||
[],
|
||||
[AbstractNormalizer::GROUPS => ["read"]]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@ use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
|
@ -527,15 +527,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
Request::METHOD_HEAD => true,
|
||||
],
|
||||
],
|
||||
'address' => [
|
||||
'methods' => [
|
||||
Request::METHOD_POST => true,
|
||||
Request::METHOD_DELETE => true,
|
||||
Request::METHOD_GET => false,
|
||||
Request::METHOD_HEAD => false,
|
||||
],
|
||||
'controller_action' => 'householdAddressApi',
|
||||
],
|
||||
'suggestHouseholdByAccompanyingPeriodParticipation' => [
|
||||
'path' => '/suggest/by-person/{person_id}/through-accompanying-period-participation.{_format}',
|
||||
'methods' => [
|
||||
|
@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
@ -22,7 +23,7 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
* @ORM\Entity
|
||||
* @ORM\Table("chill_person_accompanying_period_location_history")
|
||||
*/
|
||||
class AccompanyingPeriodLocationHistory
|
||||
class AccompanyingPeriodLocationHistory implements TrackCreationInterface
|
||||
{
|
||||
use TrackCreationTrait;
|
||||
|
||||
|
@ -106,20 +106,74 @@ class Household
|
||||
$this->compositions = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function addAddress(Address $address)
|
||||
public function addAddress(Address $address): self
|
||||
{
|
||||
foreach ($this->getAddresses() as $a) {
|
||||
if ($a->getValidFrom() <= $address->getValidFrom() && $a->getValidTo() === null) {
|
||||
$a->setValidTo($address->getValidFrom());
|
||||
if (!$this->addresses->contains($address)) {
|
||||
$this->addresses[] = $address;
|
||||
$this->makeAddressConsistent();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAddressesOrdered(): array
|
||||
{
|
||||
$addresses = $this->getAddresses()->toArray();
|
||||
usort($addresses, function (Address $a, Address $b) {
|
||||
$validFromA = $a->getValidFrom()->format('Y-m-d');
|
||||
$validFromB = $b->getValidFrom()->format('Y-m-d');
|
||||
|
||||
if ($a === $b) {
|
||||
if (null === $a->getId()) {
|
||||
return 1;
|
||||
}
|
||||
if (null === $b->getId()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return $a->getId() <=> $b->getId();
|
||||
}
|
||||
|
||||
return $validFromA <=> $validFromB;
|
||||
});
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
public function getPreviousAddressOf(Address $address): ?Address
|
||||
{
|
||||
$iterator = new ArrayIterator($this->getAddressesOrdered());
|
||||
$iterator->rewind();
|
||||
|
||||
while ($iterator->valid()) {
|
||||
$current = $iterator->current();
|
||||
$iterator->next();
|
||||
|
||||
if ($iterator->valid()) {
|
||||
if ($address === $iterator->current()) {
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->addresses[] = $address;
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this;
|
||||
public function makeAddressConsistent(): void
|
||||
{
|
||||
$iterator = new ArrayIterator($this->getAddressesOrdered());
|
||||
|
||||
$iterator->rewind();
|
||||
|
||||
while ($iterator->valid()) {
|
||||
$current = $iterator->current();
|
||||
|
||||
$iterator->next();
|
||||
|
||||
if ($iterator->valid()) {
|
||||
$current->setValidTo($iterator->current()->getValidFrom());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function addComposition(HouseholdComposition $composition): self
|
||||
|
@ -121,7 +121,7 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
|
||||
|
||||
$eventSubscriber->resetPeriodLocation($event);
|
||||
|
||||
$this->assertSame($previousAddress, $period->getAddressLocation());
|
||||
$this->assertNotNull($period->getAddressLocation());
|
||||
$this->assertNull($period->getPersonLocation());
|
||||
}
|
||||
|
||||
@ -166,7 +166,49 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
|
||||
|
||||
$eventSubscriber->resetPeriodLocation($event);
|
||||
|
||||
$this->assertSame($previousAddress, $period->getAddressLocation());
|
||||
$this->assertNotNull($period->getAddressLocation());
|
||||
$this->assertNull($period->getPersonLocation());
|
||||
}
|
||||
|
||||
public function testEventPersonChangeAddressInThePast()
|
||||
{
|
||||
$person = new Person();
|
||||
$period = new AccompanyingPeriod();
|
||||
$period
|
||||
->setStep(AccompanyingPeriod::STEP_CONFIRMED)
|
||||
->setPersonLocation($person)
|
||||
->addPerson($person)
|
||||
->setUser(new User());
|
||||
$this->forceIdToPeriod($period);
|
||||
|
||||
$membership = new HouseholdMember();
|
||||
$membership
|
||||
->setPerson($person)
|
||||
->setHousehold($household = new Household())
|
||||
->setStartDate(new DateTimeImmutable('1 year ago'))
|
||||
;
|
||||
|
||||
$previousAddress = new Address();
|
||||
$previousAddress->setValidFrom(new DateTime('6 months ago'));
|
||||
$household->addAddress($previousAddress);
|
||||
|
||||
$newAddress = new Address();
|
||||
$newAddress->setValidFrom(new DateTime('tomorrow'));
|
||||
$household->addAddress($newAddress);
|
||||
|
||||
$event = new PersonAddressMoveEvent($person);
|
||||
$event
|
||||
->setPreviousAddress($household->getPreviousAddressOf($newAddress))
|
||||
->setNextAddress($newAddress)
|
||||
;
|
||||
|
||||
$em = $this->prophesize(EntityManagerInterface::class);
|
||||
$em->persist(Argument::type(Notification::class))->shouldBeCalledTimes(1);
|
||||
$eventSubscriber = $this->buildSubscriber(null, $em->reveal(), null, null);
|
||||
|
||||
$eventSubscriber->resetPeriodLocation($event);
|
||||
|
||||
$this->assertNotNull($period->getAddressLocation());
|
||||
$this->assertNull($period->getPersonLocation());
|
||||
}
|
||||
|
||||
@ -201,7 +243,7 @@ final class PersonMoveEventSubscriberTest extends KernelTestCase
|
||||
|
||||
$eventSubscriber->resetPeriodLocation($event);
|
||||
|
||||
$this->assertSame($previousAddress, $period->getAddressLocation());
|
||||
$this->assertNotNull($period->getAddressLocation());
|
||||
$this->assertNull($period->getPersonLocation());
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Entity\Household;
|
||||
|
||||
use Chill\MainBundle\Entity\Address;
|
||||
use Chill\PersonBundle\Entity\Household\Household;
|
||||
use Chill\PersonBundle\Entity\Household\HouseholdComposition;
|
||||
use DateTimeImmutable;
|
||||
use DateTime;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
@ -44,4 +46,43 @@ final class HouseholdTest extends TestCase
|
||||
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $second->getStartDate());
|
||||
$this->assertEquals(new DateTimeImmutable('2021-12-31'), $inside->getEndDate());
|
||||
}
|
||||
|
||||
public function testHouseholdAddressConsistent()
|
||||
{
|
||||
$household = new Household();
|
||||
|
||||
$lastAddress = new Address();
|
||||
$lastAddress->setValidFrom($yesterday = new DateTime('yesterday'));
|
||||
$household->addAddress($lastAddress);
|
||||
|
||||
$this->assertNull($lastAddress->getValidTo());
|
||||
$this->assertEquals($yesterday, $lastAddress->getValidFrom());
|
||||
|
||||
$previousAddress = new Address();
|
||||
$previousAddress->setValidFrom($oneMonthAgo = new DateTime('1 month ago'));
|
||||
$household->addAddress($previousAddress);
|
||||
|
||||
$addresses = $household->getAddressesOrdered();
|
||||
$this->assertSame($previousAddress, $addresses[0]);
|
||||
$this->assertSame($lastAddress, $addresses[1]);
|
||||
|
||||
$this->assertEquals($oneMonthAgo, $previousAddress->getValidFrom());
|
||||
$this->assertEquals($yesterday, $previousAddress->getValidTo());
|
||||
$this->assertEquals($yesterday, $lastAddress->getValidFrom());
|
||||
$this->assertNull($lastAddress->getValidTo());
|
||||
|
||||
$futureAddress = new Address();
|
||||
$futureAddress->setValidFrom(new DateTime('tomorrow'));
|
||||
$household->addAddress($futureAddress);
|
||||
|
||||
$addresses = $household->getAddressesOrdered();
|
||||
$this->assertSame($previousAddress, $addresses[0]);
|
||||
$this->assertSame($lastAddress, $addresses[1]);
|
||||
$this->assertSame($futureAddress, $addresses[2]);
|
||||
|
||||
$this->assertEquals($oneMonthAgo, $previousAddress->getValidFrom());
|
||||
$this->assertEquals($yesterday, $previousAddress->getValidTo());
|
||||
$this->assertEquals($yesterday, $lastAddress->getValidFrom());
|
||||
$this->assertNull($lastAddress->getValidTo());
|
||||
}
|
||||
}
|
||||
|
@ -30,11 +30,6 @@ final class PersonAddressMoveEventTest extends TestCase
|
||||
public function testPersonChangeHousehold()
|
||||
{
|
||||
$person = new Person();
|
||||
$period = new AccompanyingPeriod();
|
||||
$period
|
||||
->setStep(AccompanyingPeriod::STEP_CONFIRMED)
|
||||
->setPersonLocation($person)
|
||||
->addPerson($person);
|
||||
|
||||
$previousHousehold = (new Household())->addAddress(
|
||||
($previousAddress = new Address())->setValidFrom(new DateTime('1 year ago'))
|
||||
@ -71,11 +66,6 @@ final class PersonAddressMoveEventTest extends TestCase
|
||||
public function testPersonLeaveHousehold()
|
||||
{
|
||||
$person = new Person();
|
||||
$period = new AccompanyingPeriod();
|
||||
$period
|
||||
->setStep(AccompanyingPeriod::STEP_CONFIRMED)
|
||||
->setPersonLocation($person)
|
||||
->addPerson($person);
|
||||
|
||||
$previousHousehold = (new Household())->addAddress(
|
||||
($previousAddress = new Address())->setValidFrom(new DateTime('1 year ago'))
|
||||
@ -98,4 +88,32 @@ final class PersonAddressMoveEventTest extends TestCase
|
||||
$this->assertTrue($event->personLeaveWithoutHousehold());
|
||||
$this->assertEquals(new DateTimeImmutable('tomorrow'), $event->getMoveDate());
|
||||
}
|
||||
|
||||
public function testPersonChangeAddress()
|
||||
{
|
||||
$person = new Person();
|
||||
|
||||
$household = (new Household())->addAddress(
|
||||
($previousAddress = new Address())->setValidFrom(new DateTime('1 year ago'))
|
||||
);
|
||||
$household = (new Household())->addAddress(
|
||||
($nextAddress = new Address())->setValidFrom(new DateTime('1 month ago'))
|
||||
);
|
||||
$member = new HouseholdMember();
|
||||
$member
|
||||
->setPerson($person)
|
||||
->setHousehold($household)
|
||||
->setStartDate(new DateTimeImmutable('1 year ago'))
|
||||
->setEndDate(new DateTimeImmutable('tomorrow'));
|
||||
|
||||
$event = new PersonAddressMoveEvent($person);
|
||||
$event
|
||||
->setPreviousAddress($previousAddress)
|
||||
->setNextAddress($nextAddress);
|
||||
|
||||
$this->assertSame($previousAddress, $event->getPreviousAddress());
|
||||
$this->assertSame($nextAddress, $event->getNextAddress());
|
||||
$this->assertEquals(new DateTime('tomorrow'), $nextAddress->getValidFrom());
|
||||
$this->assertEquals(new DateTime('tomorrow'), $event->getMoveDate());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user