readBool($request->query->get('includeArchived')); $archivedOnly = $this->readBool($request->query->get('archivedOnly')); $search = $request->query->getString('search') ?: null; $certificationTypes = $this->readStringList($request->query->all()['certificationType'] ?? []); /** @var list $carriers */ $carriers = $this->repository ->createListQueryBuilder($includeArchived, $search, $certificationTypes, $archivedOnly) ->getQuery() ->getResult() ; $binary = $this->exporter->export( 'Répertoire transporteurs', $this->buildHeaders(), $this->buildRows($carriers), ); return $this->buildResponse($binary); } /** * Colonnes de l'export (spec § 4.6). * * @return list */ private function buildHeaders(): array { return [ 'Nom', 'Certification', 'Statut QUALIMAT', 'Date de validité', 'Affrété', 'Volume m³', 'Date de création', ]; } /** * @param list $carriers * * @return iterable> */ private function buildRows(array $carriers): iterable { foreach ($carriers as $carrier) { // Statut / date de validite proviennent du referentiel QUALIMAT lie // (RG-4.04), deja fetch-joine par le repository (anti N+1, § 2.11). $qualimat = $carrier->getQualimatCarrier(); yield [ $carrier->getName(), $carrier->getCertificationType() ?? '', $qualimat?->getStatus() ?? '', $qualimat?->getValidityDate()?->format('d/m/Y') ?? '', $carrier->isChartered() ? 'Oui' : 'Non', $carrier->getVolumeM3() ?? '', $carrier->getCreatedAt()?->format('d/m/Y'), ]; } } private function buildResponse(string $binary): Response { $filename = sprintf('repertoire-transporteurs-%s.xlsx', new DateTimeImmutable()->format('Ymd')); $response = new Response($binary); $response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s"', $filename)); return $response; } /** * Lit un flag booleen issu des query params. Accepte true / "true" / "1". * Aligne sur CarrierProvider pour un comportement identique a la liste. */ private function readBool(mixed $raw): bool { return is_string($raw) && in_array(strtolower($raw), ['true', '1'], true); } /** * Normalise un filtre en liste de chaines (valeur unique ou liste). * Aligne sur CarrierProvider pour un comportement identique a la liste. * * @return list */ private function readStringList(mixed $raw): array { $values = is_array($raw) ? $raw : [$raw]; $out = []; foreach ($values as $value) { if (is_string($value) && '' !== trim($value)) { $out[] = trim($value); } } return $out; } }