Ajoute la gestion de l'upsert des utilisateurs avec un nouveau handler et un message d'upsert, met à jour les dépendances et ajoute une méthode pour trouver un utilisateur par son identifiant externe.

This commit is contained in:
Boris Waaub
2026-02-23 10:18:52 +01:00
parent 590f4121d0
commit 312dbf6cda
5 changed files with 112 additions and 3 deletions

View File

@@ -0,0 +1,83 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\Bundle\ChillPersonBundle\Entity\Person\Upsert\Handler;
use Chill\PersonBundle\Repository\PersonRepository;
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\Entity\Person\Upsert\UpsertMessage;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Doctrine\ORM\EntityManagerInterface;
#[AsMessageHandler]
class PersonUpsertHandler
{
public function __construct(
// TODO: Utiliser findByExternalId à la place de findByDefinitionAndCanonical ?
private readonly PersonRepository $personRepository,
private readonly PersonIdentifierDefinitionRepository $personIdentifierDefinitionRepository,
private readonly PersonIdentifierRepository $personIdentifierRepository,
private readonly EntityManagerInterface $entityManager,
) {}
public function __invoke(UpsertMessage $message): void
{
// 1. Récupérer la définition
$definition = $this->personIdentifierDefinitionRepository->find($message->personIdentifierDefinitionId);
if (!$definition) {
throw new \RuntimeException('PersonIdentifierDefinition non trouvée pour l\'id '.$message->personIdentifierDefinitionId);
}
// 2. Chercher les identifiants
$identifiers = $this->personIdentifierRepository->findByDefinitionAndCanonical($definition, $message->externalId);
if (count($identifiers) > 1) {
throw new \RuntimeException('Plus d\'un identifiant trouvé pour la définition et la valeur donnée.');
}
if (0 === count($identifiers)) {
// 3. Créer une nouvelle entité Person
$person = new Person();
if (null !== $message->firstName) {
$person->setFirstName($message->firstName);
}
if (null !== $message->lastName) {
$person->setLastName($message->lastName);
}
$this->entityManager->persist($person);
// Créer l'identifiant et l'associer
$identifier = new PersonIdentifier($definition);
$identifier->setPerson($person);
$identifier->setValue(['content' => $message->externalId]);
$this->entityManager->persist($identifier);
} else {
// 4. Mettre à jour le Person existant
/** @var PersonIdentifier $identifier */
$identifier = $identifiers[0];
$person = $identifier->getPerson();
if (null === $person) {
throw new \RuntimeException('L\'identifiant trouvé n\'est lié à aucun Person.');
}
if (null !== $message->firstName) {
$person->setFirstName($message->firstName);
}
if (null !== $message->lastName) {
$person->setLastName($message->lastName);
}
}
$this->entityManager->flush();
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Entity\Person\Upsert;
class UpsertMessage
{
public string $externalId;
public int $personIdentifierDefinitionId;
public ?string $firstName = null;
public ?string $lastName = null;
}

View File

@@ -73,6 +73,11 @@ class PersonRepository implements ObjectRepository
return $this->repository->findBy(['id' => $ids]);
}
public function findByExternalId(string $externalId): ?Person
{
return $this->repository->findOneBy(['externalId' => $externalId]);
}
/**
* @throws \Exception
*