Handle address message

This commit is contained in:
Boris Waaub
2026-03-04 10:00:13 +01:00
parent b194d4c5c3
commit 96589c2da4
2 changed files with 111 additions and 3 deletions

View File

@@ -11,11 +11,18 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Actions\Upsert\Handler;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Repository\PostalCodeRepositoryInterface;
use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Household\MembersEditorFactory;
use Chill\PersonBundle\Repository\Household\PositionRepository;
use Chill\PersonBundle\Repository\Identifier\PersonIdentifierDefinitionRepository;
use Chill\PersonBundle\Repository\Identifier\PersonIdentifierRepository;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
use Chill\PersonBundle\Actions\Upsert\UpsertMessage;
use Symfony\Component\Clock\Clock;
use Symfony\Component\Clock\ClockInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Doctrine\ORM\EntityManagerInterface;
@@ -26,10 +33,105 @@ readonly class PersonUpsertHandler
private PersonIdentifierDefinitionRepository $personIdentifierDefinitionRepository,
private PersonIdentifierRepository $personIdentifierRepository,
private EntityManagerInterface $entityManager,
private MembersEditorFactory $membersEditorFactory,
private PostalCodeRepositoryInterface $postalCodeRepository,
private PositionRepository $positionRepository,
private ClockInterface $clock,
) {}
private function _handlePersonMessage(UpsertMessage $message, Person $person): Person
private function createAddressWithMessage(UpsertMessage $message): Address
{
$newAddress = new Address();
if (null !== $message->address) {
$newAddress->setStreet($message->address);
}
if (null !== $message->streetNumber) {
$newAddress->setStreetNumber($message->streetNumber);
}
if (null !== $message->postcode) {
$postalCode = $this->postalCodeRepository->findOneBy(['code' => $message->postcode]);
if (null !== $postalCode) {
$newAddress->setPostcode($postalCode);
}
}
if (null !== $message->extra) {
$newAddress->setExtra($message->extra);
}
$newAddress->setValidFrom(\DateTime::createFromImmutable($this->clock->now()));
return $newAddress;
}
private function messageAddressExistsAddresses(array $currentAddresses, UpsertMessage $message): bool
{
foreach ($currentAddresses as $existingAddress) {
$streetMatches = $message->address === $existingAddress->getStreet();
$streetNumberMatches = $message->streetNumber === $existingAddress->getStreetNumber();
$postcodeMatches = null !== $existingAddress->getPostcode()
&& $message->postcode === $existingAddress->getPostcode()->getCode();
if ($streetMatches && $streetNumberMatches && $postcodeMatches) {
return true;
}
}
return false;
}
private function handlePersonMessage(UpsertMessage $message, Person $person): Person
{
$membersEditor = $this->membersEditorFactory->createEditor();
$currentHousehold = $person->getCurrentHousehold();
// Check if address information is provided in the message
$hasAddressInfo = $message->hasAddressInfo();
if (null !== $currentHousehold && $hasAddressInfo) {
$currentAddresses = $currentHousehold->getAddresses()->toArray();
$addressMatches = $this->messageAddressExistsAddresses($currentAddresses, $message);
if (!$addressMatches) {
$newAddress = $this->createAddressWithMessage($message);
$currentHousehold->addAddress($newAddress);
}
} elseif (null === $currentHousehold && $hasAddressInfo) {
// Create a new household with a new address
$newHousehold = new Household();
// Create the new address
$newAddress = $this->createAddressWithMessage($message);
$newHousehold->addAddress($newAddress);
// Find a default position (first one ordered by ordering)
$positions = $this->positionRepository->findByActiveOrdered();
$defaultPosition = count($positions) > 0 ? $positions[0] : null;
// Create a MembersEditor with the new household and add the person
$membersEditor = $this->membersEditorFactory->createEditor($newHousehold);
$membersEditor->addMovement(
$this->clock->now(),
$person,
$defaultPosition,
true
);
// Validate the membership
$violations = $membersEditor->validate();
if ($violations->count() > 0) {
// Handle validation errors - for now we'll just skip household creation
// In production, you might want to log this or throw an exception
} else {
// Persist the household and trigger events
$this->entityManager->persist($newHousehold);
foreach ($membersEditor->getPersistable() as $persistable) {
$this->entityManager->persist($persistable);
}
$membersEditor->postMove();
}
}
// Update person information
if (null !== $message->firstName) {
$person->setFirstName($message->firstName);
}
@@ -37,6 +139,7 @@ readonly class PersonUpsertHandler
$person->setLastName($message->lastName);
}
// @todo add gender and center
return $person;
}
@@ -58,7 +161,7 @@ readonly class PersonUpsertHandler
if (0 === count($identifiers)) {
// 3. Create new entity Person
$person = new Person();
$person = $this->_handlePersonMessage($message, $person);
$person = $this->handlePersonMessage($message, $person);
$this->entityManager->persist($person);
// Create and bound identifier
@@ -71,7 +174,7 @@ readonly class PersonUpsertHandler
/** @var PersonIdentifier $identifier */
$identifier = $identifiers[0];
$person = $identifier->getPerson();
$person = $this->_handlePersonMessage($message, $person);
$person = $this->handlePersonMessage($message, $person);
}
$this->entityManager->flush();

View File

@@ -26,4 +26,9 @@ class UpsertMessage
public ?string $streetNumber = null;
public ?string $postcode = null;
public ?string $city = null;
public function hasAddressInfo(): bool
{
return null !== $this->address || null !== $this->postcode || null !== $this->streetNumber;
}
}