diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index 880c2bd11..59570f956 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -328,6 +328,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * targetEntity=HouseholdMember::class, * mappedBy="person" * ) + * + * @var Collection|HouseholdMember[] */ private Collection $householdParticipations; @@ -1117,6 +1119,9 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI return $this->householdAddresses; } + /** + * @return Collection|HouseholdMember[] + */ public function getHouseholdParticipations(): Collection { return $this->householdParticipations; @@ -1126,6 +1131,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * Get participation where the person does not share the household. * * Order by startDate, desc + * + * @return HouseholdMember[] */ public function getHouseholdParticipationsNotShareHousehold(): Collection { @@ -1146,6 +1153,8 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI * Get participation where the person does share the household. * * Order by startDate, desc + * + * @return Collection|HouseholdMember[] */ public function getHouseholdParticipationsShareHousehold(): Collection { diff --git a/src/Bundle/ChillPersonBundle/Household/MembersEditor.php b/src/Bundle/ChillPersonBundle/Household/MembersEditor.php index fd2fcfbb2..812307a14 100644 --- a/src/Bundle/ChillPersonBundle/Household/MembersEditor.php +++ b/src/Bundle/ChillPersonBundle/Household/MembersEditor.php @@ -70,10 +70,12 @@ class MembersEditor $this->household->addMember($membership); if ($position->getShareHousehold()) { - // launch event only if moving to a "share household" position + // launch event only if moving to a "share household" position, + // and if the destination household is different than the previous one $event = new PersonAddressMoveEvent($person); $event->setNextMembership($membership); - $this->events[] = $event; + + $counter = 0; foreach ($person->getHouseholdParticipationsShareHousehold() as $participation) { if ($participation === $membership) { @@ -84,14 +86,25 @@ class MembersEditor continue; } + ++$counter; + if ($participation->getEndDate() === null || $participation->getEndDate() > $date) { - $event->setPreviousMembership($participation); $participation->setEndDate($date); $this->membershipsAffected[] = $participation; $this->oldMembershipsHashes[] = spl_object_hash($participation); + + if ($participation->getHousehold() !== $this->household) { + $event->setPreviousMembership($participation); + $this->events[] = $event; + } } } + // send also the event if there was no participation before + if (0 === $counter) { + $this->events[] = $event; + } + foreach ($person->getHouseholdParticipationsNotShareHousehold() as $participation) { if ($participation->getHousehold() === $this->household && $participation->getEndDate() === null || $participation->getEndDate() > $membership->getStartDate() diff --git a/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php b/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php index a5d34b1dc..69603031a 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Household/MembersEditorTest.php @@ -231,13 +231,71 @@ final class MembersEditorTest extends TestCase $editor->postMove(); } - public function testPostMoveToAPositionSharingHousehold() + public function testPostMoveToAPositionSharingHouseholdAndSameHousehold() + { + $person = new Person(); + $position = (new Position()) + ->setShareHousehold(true); + $position2 = (new Position()) + ->setShareHousehold(true); + $household1 = new Household(); + + // set into the first household + $editor = $this->buildMembersEditorFactory() + ->createEditor($household1); + $editor->addMovement(new DateTimeImmutable('1 year ago'), $person, $position); + + // prepare for next move + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher + ->dispatch(Argument::type(PersonAddressMoveEvent::class)) + ->shouldNotBeCalled(); + $factory = $this->buildMembersEditorFactory( + $eventDispatcher->reveal(), + null + ); + $editor = $factory->createEditor($household1); + + $editor->addMovement(new DateTimeImmutable('now'), $person, $position2); + + $editor->postMove(); + } + + public function testPostMoveToAPositionSharingHouseholdFromDifferentHousehold() { $person = new Person(); $position = (new Position()) ->setShareHousehold(true); $household1 = new Household(); $household2 = new Household(); + + // set into the first household + $editor = $this->buildMembersEditorFactory() + ->createEditor($household1); + $editor->addMovement(new DateTimeImmutable('1 year ago'), $person, $position); + + // perform now the movement + $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); + $eventDispatcher + ->dispatch(Argument::type(PersonAddressMoveEvent::class)) + ->shouldBeCalled(); + $factory = $this->buildMembersEditorFactory( + $eventDispatcher->reveal(), + null + ); + $editor = $factory->createEditor($household2); + + $editor->addMovement(new DateTimeImmutable('now'), $person, $position); + + $editor->postMove(); + } + + public function testPostMoveToAPositionSharingHouseholdFromNoHousehold() + { + $person = new Person(); + $position = (new Position()) + ->setShareHousehold(true); + $household1 = new Household(); $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); $eventDispatcher ->dispatch(Argument::type(PersonAddressMoveEvent::class))