*/ final class BovinInventoryProvider implements ProviderInterface { public function __construct( private BovinApiInterface $bovinApi, private RequestStack $requestStack, private AnimalSummaryMapper $animalSummaryMapper, ) {} public function provide(Operation $operation, array $uriVariables = [], array $context = []): ?BovinInventory { $startDateRaw = (string) ($uriVariables['startDate'] ?? ''); if ('' === $startDateRaw) { return null; } try { $startDate = new DateTimeImmutable($startDateRaw); } catch (Exception) { return null; } $request = $this->requestStack->getCurrentRequest(); $endDate = null; $endDateRaw = $request?->query->get('endDate'); if (is_string($endDateRaw) && '' !== $endDateRaw) { try { $endDate = new DateTimeImmutable($endDateRaw); } catch (Exception) { return null; } } $includeEarTagStock = (bool) $request?->query->getBoolean('includeEarTagStock', false); $inventoryDto = $this->bovinApi->getInventory( startDate: $startDate, endDate: $endDate, includeEarTagStock: $includeEarTagStock, ); $resource = new BovinInventory(); $resource->startDate = $inventoryDto->startDate?->format('Y-m-d') ?? $startDate->format('Y-m-d'); $resource->endDate = $inventoryDto->endDate?->format('Y-m-d'); $resource->includesEarTagStock = $inventoryDto->includesEarTagStock; $resource->nbBovins = $inventoryDto->nbBovins; $resource->earTagSeriesCount = count($inventoryDto->earTagSeries); foreach ($inventoryDto->animals as $animalDto) { $resource->animals[] = $this->animalSummaryMapper->map($animalDto); } return $resource; } }