*/ final class BovineSyncInventoryProcessor implements ProcessorInterface { /** * @var array */ private array $bovineTypeCache = []; public function __construct( private BovinApiInterface $bovinApi, private EntityManagerInterface $em, ) {} public function process( mixed $data, Operation $operation, array $uriVariables = [], array $context = [], ): BovineSyncInventoryResult { $inventory = $this->bovinApi->getInventory(new DateTimeImmutable('today')); $result = new BovineSyncInventoryResult(); $result->total = count($inventory->animals); $this->bovineTypeCache = []; foreach ($this->em->getRepository(BovineType::class)->findAll() as $bovineType) { if (null !== $bovineType->getCode()) { $this->bovineTypeCache[$bovineType->getCode()] = $bovineType; } } $existingByNationalNumber = []; foreach ($this->em->getRepository(Bovine::class)->findAll() as $bovine) { $existingByNationalNumber[$bovine->getNationalNumber()] = $bovine; } $seen = []; foreach ($inventory->animals as $animal) { $nationalNumber = $animal->identification?->bovin?->nationalNumber; if (null === $nationalNumber || '' === $nationalNumber) { continue; } $seen[$nationalNumber] = true; if (isset($existingByNationalNumber[$nationalNumber])) { $bovine = $existingByNationalNumber[$nationalNumber]; ++$result->updated; } else { $bovine = new Bovine(); $bovine->setNationalNumber($nationalNumber); $this->em->persist($bovine); ++$result->created; } $this->applyEdnotifData($bovine, $animal); $bovine->setExitedAt(null); } $now = new DateTimeImmutable(); foreach ($existingByNationalNumber as $nationalNumber => $bovine) { if (isset($seen[$nationalNumber])) { continue; } if (null !== $bovine->getExitedAt()) { continue; } $bovine->setExitedAt($now); ++$result->exited; } $this->em->flush(); return $result; } private function applyEdnotifData(Bovine $bovine, AnimalSummaryDto $animal): void { $identification = $animal->identification; if (null !== $identification) { $bovine->setSex($identification->sex); $bovine->setBovineType($this->resolveBovineType($identification->breedType)); $bovine->setWorkNumber($identification->workNumber); $bovine->setBirthDate($identification->birthDate?->date); } $latestEntry = null; $latestExit = null; foreach ($animal->presencePeriods as $period) { if (null !== $period->entry?->date && (null === $latestEntry || $period->entry->date > $latestEntry)) { $latestEntry = $period->entry->date; } if (null !== $period->exit?->date && (null === $latestExit || $period->exit->date > $latestExit)) { $latestExit = $period->exit->date; } } $bovine->setArrivalDate($latestEntry); $bovine->setExitDate($latestExit); $bovine->refreshAgeMonths(); } /** * Trouve un BovineType existant par code, sinon en crée un placeholder * que l'admin pourra renommer dans /admin/bovin/bovin-list. */ private function resolveBovineType(?string $code): ?BovineType { if (null === $code || '' === $code) { return null; } if (isset($this->bovineTypeCache[$code])) { return $this->bovineTypeCache[$code]; } $bovineType = new BovineType(); $bovineType->setCode($code); $bovineType->setLabel(sprintf('À renommer (%s)', $code)); $this->em->persist($bovineType); $this->bovineTypeCache[$code] = $bovineType; return $bovineType; } }