exclue de * EntitiesAreTimestampableBlamableTest et non #[Auditable]. */ #[ApiResource( operations: [ // Saisie assistee (§ 4.7 / RG-4.01) : ?search= fuzzy name (+ siret), // SEULEMENT les lignes actives, tri name ASC, paginee. La logique vit // dans le provider (forcage is_active + recherche multi-champs) car un // SearchFilter natif ne sait ni unifier name/siret sous un seul ?search=, // ni imposer cote serveur le filtre actif. new GetCollection( security: "is_granted('transport.carriers.view')", provider: QualimatCarrierSearchProvider::class, normalizationContext: ['groups' => ['qualimat:read', 'default:read']], ), new Get( security: "is_granted('transport.carriers.view')", normalizationContext: ['groups' => ['qualimat:read', 'default:read']], ), ], )] #[ORM\Entity] // Mapping reproduisant a l'identique le DDL de la migration ERP-39 // (Version20260612150000) pour que `schema:update --force` reste un no-op : // contrainte d'unicite siret + index is_active. #[ORM\Table(name: 'qualimat_carrier')] #[ORM\UniqueConstraint(name: 'uq_qualimat_carrier_siret', columns: ['siret'])] #[ORM\Index(name: 'idx_qualimat_carrier_active', columns: ['is_active'])] class QualimatCarrier { #[ORM\Id] #[ORM\GeneratedValue(strategy: 'IDENTITY')] #[ORM\Column(type: 'bigint')] #[Groups(['qualimat:read'])] private ?string $id = null; #[ORM\Column(length: 20)] #[Groups(['qualimat:read'])] private ?string $siret = null; #[ORM\Column(length: 255)] #[Groups(['qualimat:read'])] private ?string $name = null; #[ORM\Column(length: 255, nullable: true)] #[Groups(['qualimat:read'])] private ?string $address = null; #[ORM\Column(name: 'postal_code', length: 10, nullable: true)] #[Groups(['qualimat:read'])] private ?string $postalCode = null; #[ORM\Column(length: 255, nullable: true)] #[Groups(['qualimat:read'])] private ?string $city = null; #[ORM\Column(length: 32, nullable: true)] #[Groups(['qualimat:read'])] private ?string $phone = null; #[ORM\Column(length: 64, nullable: true)] #[Groups(['qualimat:read'])] private ?string $department = null; #[ORM\Column(length: 32)] #[Groups(['qualimat:read'])] private ?string $status = null; #[ORM\Column(name: 'validity_date', type: 'date_immutable', nullable: true)] #[Groups(['qualimat:read'])] private ?DateTimeImmutable $validityDate = null; #[ORM\Column(name: 'is_active', options: ['default' => true])] #[Groups(['qualimat:read'])] #[SerializedName('isActive')] private bool $isActive = true; // Colonne technique de synchro (soft-delete) — mappee pour completude, non // serialisee. Alimentee par app:qualimat:sync. columnDefinition pin la // precision TIMESTAMP(6) du DDL ERP-39 pour eviter un ALTER de schema:update // (le datetime_immutable par defaut mapperait sur TIMESTAMP(0)). #[ORM\Column(name: 'last_synced_at', type: 'datetime_immutable', columnDefinition: 'TIMESTAMP(6) WITHOUT TIME ZONE NOT NULL')] private ?DateTimeImmutable $lastSyncedAt = null; public function getId(): ?string { return $this->id; } public function getSiret(): ?string { return $this->siret; } public function getName(): ?string { return $this->name; } public function getAddress(): ?string { return $this->address; } public function getPostalCode(): ?string { return $this->postalCode; } public function getCity(): ?string { return $this->city; } public function getPhone(): ?string { return $this->phone; } public function getDepartment(): ?string { return $this->department; } public function getStatus(): ?string { return $this->status; } public function getValidityDate(): ?DateTimeImmutable { return $this->validityDate; } public function isActive(): bool { return $this->isActive; } public function getLastSyncedAt(): ?DateTimeImmutable { return $this->lastSyncedAt; } }