From 87ba68971c5bdec1274762ec4b60ae05cdc25055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 28 May 2021 16:41:37 +0200 Subject: [PATCH] first impl of person Mover + add fixtures --- .../DataFixtures/ORM/LoadHousehold.php | 101 ++++++++++++++++++ .../ORM/LoadHouseholdPosition.php | 38 +++++++ .../ChillPersonExtension.php | 1 + ...useholdMembers.php => HouseholdMember.php} | 68 ++++++++---- .../Entity/Household/Position.php | 4 +- .../ChillPersonBundle/Entity/Person.php | 22 ++++ src/Bundle/ChillPersonBundle/Household | 0 .../Household/MoveMembers.php | 80 ++++++++++++++ .../Household/MoveMembersFactory.php | 27 +++++ .../config/services/fixtures.yaml | 1 + .../config/services/household.yaml | 3 + .../migrations/Version20210528132405.php | 31 ++++++ .../migrations/Version20210528142121.php | 29 +++++ 13 files changed, 384 insertions(+), 21 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHousehold.php create mode 100644 src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHouseholdPosition.php rename src/Bundle/ChillPersonBundle/Entity/Household/{HouseholdMembers.php => HouseholdMember.php} (60%) delete mode 100644 src/Bundle/ChillPersonBundle/Household create mode 100644 src/Bundle/ChillPersonBundle/Household/MoveMembers.php create mode 100644 src/Bundle/ChillPersonBundle/Household/MoveMembersFactory.php create mode 100644 src/Bundle/ChillPersonBundle/config/services/household.yaml create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20210528132405.php create mode 100644 src/Bundle/ChillPersonBundle/migrations/Version20210528142121.php diff --git a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHousehold.php b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHousehold.php new file mode 100644 index 000000000..a8c3c73be --- /dev/null +++ b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHousehold.php @@ -0,0 +1,101 @@ +movementFactory = $movementFactory; + $this->em = $em; + } + + public function load(ObjectManager $manager) + { + $this->preparePersonIds(); + + for ($i=0; $i < self::NUMBER_OF_HOUSEHOLD; $i++) { + $household = new Household(); + $manager->persist($household); + + $movement = $this->movementFactory->createMovement($household); + + // load adults + $k = 0; + foreach ($this->getRandomPersons(1, 3) as $person) { + $date = \DateTimeImmutable::createFromFormat('Y-m-d', '2010-01-01') + ->add(new \DateInterval('P'.\random_int(1, 200).'W')); + $position = $this->getReference(LoadHouseholdPosition::ADULT); + + $movement->addMovement($date, $person, $position, $k === 0, "self generated"); + $k++; + } + + // load children + foreach ($this->getRandomPersons(0, 3) as $person) { + $date = \DateTimeImmutable::createFromFormat('Y-m-d', '2010-01-01') + ->add(new \DateInterval('P'.\random_int(1, 200).'W')); + $position = $this->getReference(LoadHouseholdPosition::CHILD); + + $movement->addMovement($date, $person, $position, $k === 0, "self generated"); + $k++; + } + + foreach ($movement->getPersistable() as $obj) { + print($obj->getStartDate()->format('Y-m-d')); + $manager->persist($obj); + } + } + + $manager->flush(); + } + + private function preparePersonIds() + { + $this->personIds = $this->em + ->createQuery('SELECT p.id FROM '.Person::class.' p '. + 'JOIN p.center c '. + 'WHERE c.name = :center ' + ) + ->setParameter('center', 'Center A') + ->getScalarResult() + ; + \shuffle($this->personIds); + } + + private function getRandomPersons(int $min, int $max) + { + $nb = \random_int($min, $max); + + for ($i=0; $i < $nb; $i++) { + $personId = \array_pop($this->personIds)['id']; + $persons[] = $this->em->getRepository(Person::class) + ->find($personId) + ; + } + + return $persons ?? []; + } + + public function getDependencies() + { + return [ + LoadPeople::class, + LoadHouseholdPosition::class + ]; + } +} diff --git a/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHouseholdPosition.php b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHouseholdPosition.php new file mode 100644 index 000000000..cf0bf3de1 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/DataFixtures/ORM/LoadHouseholdPosition.php @@ -0,0 +1,38 @@ +setLabel([ "fr" => $name ]) + ->setAllowHolder($allowHolder) + ->setShareHousehold($share) + ->setOrdering($ordering) + ; + + $manager->persist($position); + $this->addReference($ref, $position); + } + + $manager->flush(); + } +} diff --git a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php index 27721012d..a28887c68 100644 --- a/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php +++ b/src/Bundle/ChillPersonBundle/DependencyInjection/ChillPersonExtension.php @@ -74,6 +74,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac $loader->load('services/form.yaml'); $loader->load('services/templating.yaml'); $loader->load('services/alt_names.yaml'); + $loader->load('services/household.yaml'); // We can get rid of this file when the service 'chill.person.repository.person' is no more used. // We should use the PersonRepository service instead of a custom service name. $loader->load('services/repository.yaml'); diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMembers.php b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php similarity index 60% rename from src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMembers.php rename to src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php index d39034e32..89a9f3299 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMembers.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php @@ -14,7 +14,7 @@ use Chill\PersonBundle\Entity\Household\Position; * name="chill_person_household_members" * ) */ -class HouseholdMembers +class HouseholdMember { /** * @ORM\Id @@ -26,27 +26,32 @@ class HouseholdMembers /** * @ORM\ManyToOne(targetEntity=Position::class) */ - private $position; + private ?Position $position = null; /** - * @ORM\Column(type="date") + * @ORM\Column(type="date", nullable=true, options={"default": null}) */ - private $startDate; + private ?\DateTimeImmutable $startDate = null; /** - * @ORM\Column(type="date") + * @ORM\Column(type="date", nullable= true, options={"default": null}) */ - private $endDate; + private ?\DateTimeImmutable $endDate = null; /** * @ORM\Column(type="string", length=255, nullable=true) */ - private $comment; + private ?string $comment = NULL; /** * @ORM\Column(type="boolean") */ - private $sharedHousehold; + private bool $sharedHousehold = false; + + /** + * @ORM\Column(type="boolean", options={"default": false}) + */ + private bool $holder = false; /** * @@ -55,7 +60,7 @@ class HouseholdMembers * targetEntity="\Chill\PersonBundle\Entity\Person" * ) */ - private $person; + private ?Person $person = null; /** * @@ -64,21 +69,28 @@ class HouseholdMembers * targetEntity="\Chill\PersonBundle\Entity\Household\Household" * ) */ - private $household; + private ?Household $household = null; + public function getId(): ?int { return $this->id; } - public function getPosition(): ?string + public function getPosition(): ?Position { return $this->position; } - public function setPosition(?string $position): self + public function setPosition(Position $position): self { + if ($this->position instanceof Position) { + throw new \LogicException("The position is already set. You cannot change ". + "a position of a membership"); + } + $this->position = $position; + $this->sharedHousehold = $position->getShareHousehold(); return $this; } @@ -119,17 +131,11 @@ class HouseholdMembers return $this; } - public function getSharedHousehold(): ?bool + public function getShareHousehold(): ?bool { return $this->sharedHousehold; } - public function setSharedHousehold(bool $sharedHousehold): self - { - $this->sharedHousehold = $sharedHousehold; - - return $this; - } public function getPerson(): ?Person { @@ -138,8 +144,15 @@ class HouseholdMembers public function setPerson(?Person $person): self { + if ($this->person instanceof Person) { + throw new \LogicException("You cannot change person ". + "on a membership"); + } + $this->person = $person; + $person->addHouseholdParticipation($this); + return $this; } @@ -150,8 +163,25 @@ class HouseholdMembers public function setHousehold(?Household $household): self { + if ($this->household instanceof Household) { + throw new \LogicException("You cannot change household ". + "on a membership"); + } + $this->household = $household; return $this; } + + public function setHolder(bool $holder): self + { + $this->holder = $holder; + + return $this; + } + + public function isHolder(): bool + { + return $this->holder; + } } diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Position.php b/src/Bundle/ChillPersonBundle/Entity/Household/Position.php index 60e19b25a..070399661 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/Position.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Position.php @@ -55,12 +55,12 @@ class Position return $this; } - public function getShareHouseHold(): ?bool + public function getShareHousehold(): ?bool { return $this->shareHouseHold; } - public function setShareHouseHold(bool $shareHouseHold): self + public function setShareHousehold(bool $shareHouseHold): self { $this->shareHouseHold = $shareHouseHold; diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index a4fb185fb..0d9bb7cf6 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -26,6 +26,7 @@ use ArrayIterator; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Country; use Chill\PersonBundle\Entity\MaritalStatus; +use Chill\PersonBundle\Entity\Household\HouseholdMember; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\Address; use DateTime; @@ -272,6 +273,14 @@ class Person implements HasCenterInterface */ private $fullnameCanonical; + /** + * @ORM\OneToMany( + * targetEntity=HouseholdMember::class, + * mappedBy="person" + * ) + */ + private Collection $householdParticipations; + /** * Person constructor. * @@ -284,6 +293,7 @@ class Person implements HasCenterInterface $this->addresses = new ArrayCollection(); $this->altNames = new ArrayCollection(); $this->otherPhoneNumbers = new ArrayCollection(); + $this->householdParticipations = new ArrayCollection(); if ($opening === null) { $opening = new \DateTime(); @@ -1180,4 +1190,16 @@ class Person implements HasCenterInterface $this->fullnameCanonical = $fullnameCanonical; return $this; } + + public function addHouseholdParticipation(HouseholdMember $member): self + { + $this->householdParticipations[] = $member; + + return $this; + } + + public function getHouseholdParticipations(): Collection + { + return $this->householdParticipations; + } } diff --git a/src/Bundle/ChillPersonBundle/Household b/src/Bundle/ChillPersonBundle/Household deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/Bundle/ChillPersonBundle/Household/MoveMembers.php b/src/Bundle/ChillPersonBundle/Household/MoveMembers.php new file mode 100644 index 000000000..495c4122b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Household/MoveMembers.php @@ -0,0 +1,80 @@ +validation = $validator; + } + + public function toHousehold(Household $household): self + { + $this->household = $household; + + return $this; + } + + public function addMovement(\DateTimeInterface $date, Person $person, Position $position, ?bool $holder = false, ?string $comment = null): self + { + if (NULL === $this->household) { + throw new \LogicException("You must define a household first"); + } + + $membership = (new HouseholdMember()) + ->setStartDate($date) + ->setPerson($person) + ->setPosition($position) + ->setHolder($holder) + ->setHousehold($this->household) + ->setComment($comment) + ; + + if ($position->getShareHousehold()) { + foreach ($person->getHouseholdParticipations() as $participation) { + if (FALSE === $participation->getShareHousehold()) { + continue; + } + + if ($participation === $membership) { + continue; + } + + if ($participation->getEndDate() === NULL || $participation->getEndDate() > $date) { + $participation->setEndDate($date); + $this->membershipsAffected[] = $participation; + } + } + } + + $this->membershipsAffected[] = $membership; + $this->persistables[] = $membership; + + return $this; + } + + public function validate(): ConstraintViolationListInterface + { + + } + + public function getPersistable(): array + { + return $this->persistables; + } +} diff --git a/src/Bundle/ChillPersonBundle/Household/MoveMembersFactory.php b/src/Bundle/ChillPersonBundle/Household/MoveMembersFactory.php new file mode 100644 index 000000000..6a3910fda --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Household/MoveMembersFactory.php @@ -0,0 +1,27 @@ +validator = $validator; + } + + public function createMovement(?Household $household): MoveMembers + { + $movement = new MoveMembers($this->validator); + + if ($household) { + $movement->toHousehold($household); + } + + return $movement; + } +} diff --git a/src/Bundle/ChillPersonBundle/config/services/fixtures.yaml b/src/Bundle/ChillPersonBundle/config/services/fixtures.yaml index a6becd555..72bf899f4 100644 --- a/src/Bundle/ChillPersonBundle/config/services/fixtures.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/fixtures.yaml @@ -1,5 +1,6 @@ services: Chill\PersonBundle\DataFixtures\ORM\: + autowire: true resource: ../../DataFixtures/ORM tags: [ 'doctrine.fixture.orm' ] diff --git a/src/Bundle/ChillPersonBundle/config/services/household.yaml b/src/Bundle/ChillPersonBundle/config/services/household.yaml new file mode 100644 index 000000000..99c472d91 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/config/services/household.yaml @@ -0,0 +1,3 @@ +services: + Chill\PersonBundle\Household\MoveMembersFactory: + autowire: true diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20210528132405.php b/src/Bundle/ChillPersonBundle/migrations/Version20210528132405.php new file mode 100644 index 000000000..f9e94532a --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20210528132405.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE chill_person_household_members ALTER startdate DROP NOT NULL'); + $this->addSql('ALTER TABLE chill_person_household_members ALTER enddate DROP NOT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_person_household_members ALTER startDate SET NOT NULL'); + $this->addSql('ALTER TABLE chill_person_household_members ALTER endDate SET NOT NULL'); + } +} diff --git a/src/Bundle/ChillPersonBundle/migrations/Version20210528142121.php b/src/Bundle/ChillPersonBundle/migrations/Version20210528142121.php new file mode 100644 index 000000000..4eaf149af --- /dev/null +++ b/src/Bundle/ChillPersonBundle/migrations/Version20210528142121.php @@ -0,0 +1,29 @@ +addSql('ALTER TABLE chill_person_household_members ADD holder BOOLEAN DEFAULT FALSE NOT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_person_household_members DROP COLUMN holder'); + } +}