From 498cef8cc0f94ab20e0e6f1a997aed6e8763e173 Mon Sep 17 00:00:00 2001 From: tristan Date: Wed, 17 Jun 2026 15:34:17 +0200 Subject: [PATCH] =?UTF-8?q?fix(transport)=20:=20embarque=20le=20nom=20de?= =?UTF-8?q?=20la=20d=C3=A9charge=20dans=20le=20d=C3=A9tail=20carrier=20(co?= =?UTF-8?q?nsultation/modif)=20(ERP-171)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Transport/Domain/Entity/Carrier.php | 3 ++ src/Shared/Domain/Entity/UploadedDocument.php | 6 ++- .../Api/CarrierSerializationContractTest.php | 46 ++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/Module/Transport/Domain/Entity/Carrier.php b/src/Module/Transport/Domain/Entity/Carrier.php index de39955..dc35ee7 100644 --- a/src/Module/Transport/Domain/Entity/Carrier.php +++ b/src/Module/Transport/Domain/Entity/Carrier.php @@ -81,6 +81,9 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; 'supplier:read', 'supplier_address:read', 'site:read', + // Embarque le nom de fichier de la decharge (RG-4.02) au lieu d'un + // IRI nu, pour l'affichage en consultation / modification (ERP-171). + 'uploaded_document:reference', 'default:read', ]], provider: CarrierProvider::class, diff --git a/src/Shared/Domain/Entity/UploadedDocument.php b/src/Shared/Domain/Entity/UploadedDocument.php index e1151cd..0ae76ac 100644 --- a/src/Shared/Domain/Entity/UploadedDocument.php +++ b/src/Shared/Domain/Entity/UploadedDocument.php @@ -75,8 +75,12 @@ class UploadedDocument #[Groups(['uploaded_document:read'])] private ?int $id = null; + // `uploaded_document:reference` : groupe minimal d'EMBARQUEMENT (nom de fichier + // seul, sans `storedPath`/`checksum`) pour qu'une entite parente (ex: Carrier) + // affiche le libelle du document au lieu d'un simple IRI. La parente l'ajoute a + // son `normalizationContext`. #[ORM\Column(name: 'original_filename', length: 255)] - #[Groups(['uploaded_document:read'])] + #[Groups(['uploaded_document:read', 'uploaded_document:reference'])] private string $originalFilename; #[ORM\Column(name: 'stored_path', length: 512)] diff --git a/tests/Module/Transport/Api/CarrierSerializationContractTest.php b/tests/Module/Transport/Api/CarrierSerializationContractTest.php index ba5650e..e66e9f2 100644 --- a/tests/Module/Transport/Api/CarrierSerializationContractTest.php +++ b/tests/Module/Transport/Api/CarrierSerializationContractTest.php @@ -4,9 +4,14 @@ declare(strict_types=1); namespace App\Tests\Module\Transport\Api; +use App\Module\Transport\Domain\Entity\Carrier; +use App\Shared\Domain\Entity\UploadedDocument; +use App\Tests\Module\Commercial\Api\SupplierSerializationContractTest; +use DateTimeImmutable; + /** * Tests du CONTRAT DE SERIALISATION du repertoire transporteurs (M4, spec-back - * § 4.0 / § 4.0.bis). Jumeau de {@see \App\Tests\Module\Commercial\Api\SupplierSerializationContractTest}. + * § 4.0 / § 4.0.bis). Jumeau de {@see SupplierSerializationContractTest}. * Reverifie sur le JSON REEL les pieges silencieux du M1 transposes au M4 : * - #1/#2 : relations embarquees en OBJET (pas IRI nu) — qualimatCarrier, et au * detail prices[].client / .supplier / .departureSite / .deliverySite. @@ -133,6 +138,43 @@ final class CarrierSerializationContractTest extends AbstractCarrierApiTestCase self::assertIsArray($supplierPrice['deliverySite']); } + // === Decharge (RG-4.02) embarquee en OBJET avec son nom de fichier (ERP-171) === + + public function testDetailEmbedsDischargeDocumentFilename(): void + { + $em = $this->getEm(); + + // Decharge (UploadedDocument) rattachee a un transporteur certifie AUTRE. + $document = new UploadedDocument( + originalFilename: 'decharge-test.pdf', + storedPath: '2026/06/'.bin2hex(random_bytes(8)).'.pdf', + mimeType: 'application/pdf', + sizeBytes: 1234, + checksum: hash('sha256', 'contenu'), + createdAt: new DateTimeImmutable(), + ); + $em->persist($document); + + $carrier = new Carrier(); + $carrier->setName('AUTRE DISCHARGE CO'); + $carrier->setCertificationType('AUTRE'); + $carrier->setDischargeDocument($document); + $em->persist($carrier); + $em->flush(); + + $http = $this->createAdminClient(); + $data = $http->request('GET', '/api/carriers/'.$carrier->getId(), ['headers' => ['Accept' => self::LD]])->toArray(); + + // dischargeDocument embarque en OBJET (uploaded_document:reference) avec son + // nom de fichier — sinon le front n'a qu'un IRI nu et affiche un champ vide. + self::assertArrayHasKey('dischargeDocument', $data); + self::assertIsArray($data['dischargeDocument'], 'dischargeDocument doit etre un objet embarque, pas un IRI nu.'); + self::assertSame('decharge-test.pdf', $data['dischargeDocument']['originalFilename']); + // Le groupe minimal n'expose PAS les metadonnees internes (storedPath / checksum). + self::assertArrayNotHasKey('storedPath', $data['dischargeDocument']); + self::assertArrayNotHasKey('checksum', $data['dischargeDocument']); + } + // === RBAC : 403 sans la permission view === public function testForbiddenWithoutViewPermission(): void @@ -183,7 +225,7 @@ final class CarrierSerializationContractTest extends AbstractCarrierApiTestCase * * @param array $collection * - * @return array|null + * @return null|array */ private function memberById(array $collection, int $id): ?array {