From 2cde091813334beed82daa39e6a755ad986d048b Mon Sep 17 00:00:00 2001 From: tristan Date: Wed, 22 Apr 2026 17:56:08 +0200 Subject: [PATCH] =?UTF-8?q?feat=20:=20=C3=A9tape=202/5=20-=20endpoint=20PO?= =?UTF-8?q?ST=20/bovines/sync-inventory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Appelle BovinApiInterface::getInventory() puis upsert local par nationalNumber - Marque exitedAt sur les bovins absents de la réponse EDNOTIF - Retourne les stats { created, updated, exited, total } - Admin only Co-Authored-By: Claude Opus 4.7 (1M context) --- src/ApiResource/BovineSyncInventoryResult.php | 42 ++++++++ .../Bovin/BovineSyncInventoryProcessor.php | 99 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/ApiResource/BovineSyncInventoryResult.php create mode 100644 src/State/Bovin/BovineSyncInventoryProcessor.php diff --git a/src/ApiResource/BovineSyncInventoryResult.php b/src/ApiResource/BovineSyncInventoryResult.php new file mode 100644 index 0000000..adf32ad --- /dev/null +++ b/src/ApiResource/BovineSyncInventoryResult.php @@ -0,0 +1,42 @@ + + */ +final class BovineSyncInventoryProcessor implements ProcessorInterface +{ + 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('2000-01-01')); + + $result = new BovineSyncInventoryResult(); + $result->total = count($inventory->animals); + + $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->setBreedCode($identification->breedType); + $bovine->setWorkNumber($identification->workNumber); + $bovine->setBirthDate($identification->birthDate?->date); + } + + foreach ($animal->presencePeriods as $period) { + if (null === $period->exit && null !== $period->entry?->date) { + $bovine->setArrivalDate($period->entry->date); + + break; + } + } + } +}