From 50dd660713ee2404b2b18fb676dece17cc211a12 Mon Sep 17 00:00:00 2001 From: tristan Date: Thu, 21 May 2026 11:33:17 +0200 Subject: [PATCH] =?UTF-8?q?feat(bovine-type)=20:=20piloter=20l'affichage?= =?UTF-8?q?=20en=20r=C3=A9ception=20via=20un=20champ=20display=20[#FER-30]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute un champ display (défaut false) sur BovineType : seuls les types activés par un admin apparaissent à la sélection des races en réception. Les types créés par la synchro inventaire restent masqués par défaut. - Affichage des races en grille 4 colonnes (création réception) - Édition réception : conserve les types déjà saisis même masqués - Admin : badge "Affiché en réception" + checkbox dans le formulaire Co-Authored-By: Claude Opus 4.7 (1M context) --- .../reception/reception-bovine-received.vue | 13 ++++----- .../components/reception/update-bovin.vue | 22 ++++++++++++-- frontend/pages/admin/bovin/[[id]].vue | 13 ++++++--- frontend/pages/admin/bovin/bovin-list.vue | 11 ++++++- frontend/services/bovine-type.ts | 14 ++++++--- frontend/services/dto/bovine-type-data.ts | 3 ++ migrations/Version20260521092455.php | 29 +++++++++++++++++++ src/Entity/BovineType.php | 23 +++++++++++++++ 8 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 migrations/Version20260521092455.php diff --git a/frontend/components/reception/reception-bovine-received.vue b/frontend/components/reception/reception-bovine-received.vue index 78317f5..a40fe4c 100644 --- a/frontend/components/reception/reception-bovine-received.vue +++ b/frontend/components/reception/reception-bovine-received.vue @@ -5,12 +5,10 @@ @submit.prevent="goNext" >

Sélection des races réceptionnées

-
+
+ :key="type.id">
-
+
@@ -79,7 +76,7 @@ const totalBovines = computed(() => { const loadBovineType = async () => { isLoadingBovineType.value = true try { - bovineType.value = await getBovineTypeList() + bovineType.value = await getBovineTypeList({ display: true }) } finally { isLoadingBovineType.value = false } diff --git a/frontend/components/reception/update-bovin.vue b/frontend/components/reception/update-bovin.vue index 2e21df2..c3925ab 100644 --- a/frontend/components/reception/update-bovin.vue +++ b/frontend/components/reception/update-bovin.vue @@ -29,7 +29,7 @@ diff --git a/frontend/pages/admin/bovin/[[id]].vue b/frontend/pages/admin/bovin/[[id]].vue index 117e8dd..d76a520 100644 --- a/frontend/pages/admin/bovin/[[id]].vue +++ b/frontend/pages/admin/bovin/[[id]].vue @@ -14,10 +14,13 @@
-
+
+
+ +
({ label: '', - code: '' + code: '', + display: false }) @@ -64,6 +68,7 @@ const hydrateFromBovin = (bovin: BovineTypeData | null) => { isHydrating.value = true form.label = bovin.label ?? '' form.code = bovin.code ?? '' + form.display = bovin.display ?? false isHydrating.value = false } @@ -92,8 +97,8 @@ async function validate() { const basePayload = { label: normalizedBovinLabel, - code: normalizedBovinCode - + code: normalizedBovinCode, + display: form.display } isLoading.value = true diff --git a/frontend/pages/admin/bovin/bovin-list.vue b/frontend/pages/admin/bovin/bovin-list.vue index 933b8fc..3328698 100644 --- a/frontend/pages/admin/bovin/bovin-list.vue +++ b/frontend/pages/admin/bovin/bovin-list.vue @@ -29,6 +29,14 @@ +
@@ -58,7 +66,8 @@ const { items, totalItems, page, perPage, filters, loading, reload } = const columns = [ { key: 'label', label: 'Nom' }, - { key: 'code', label: 'Code' } + { key: 'code', label: 'Code' }, + { key: 'display', label: 'Affiché en réception' } ] const goToBovin = (bovin: BovineTypeData) => { diff --git a/frontend/services/bovine-type.ts b/frontend/services/bovine-type.ts index 1ca98f1..880c725 100644 --- a/frontend/services/bovine-type.ts +++ b/frontend/services/bovine-type.ts @@ -5,9 +5,13 @@ export type BovineTypeListResponse = | BovineTypeData[] | { 'hydra:member'?: BovineTypeData[] } -export async function getBovineTypeList(): Promise { +export async function getBovineTypeList(filters: { display?: boolean } = {}): Promise { const api = useApi() - const response = await api.get('bovine_types', {}, { + const query: Record = {} + if (filters.display !== undefined) { + query.display = filters.display ? 'true' : 'false' + } + const response = await api.get('bovine_types', query, { toastErrorKey: 'errors.bovin.list' }) @@ -51,10 +55,12 @@ export async function updateBovin(id: number, payload: BovinPayload = {}): Promi const mapToBovineTypeData = (item: BovineTypeData): BovineTypeData => ({ id: item.id, label: item.label, - code: item.code + code: item.code, + display: item.display ?? false }) const toBovineTypePayload = (payload: BovinPayload): Partial => ({ label: payload.label ?? undefined, - code: payload.code ?? undefined + code: payload.code ?? undefined, + display: payload.display ?? undefined }) diff --git a/frontend/services/dto/bovine-type-data.ts b/frontend/services/dto/bovine-type-data.ts index c7bba66..26293d4 100644 --- a/frontend/services/dto/bovine-type-data.ts +++ b/frontend/services/dto/bovine-type-data.ts @@ -2,14 +2,17 @@ export interface BovineTypeData{ id: number label: string code: string + display: boolean } export interface BovinFormData { label: string code: string + display: boolean } export type BovinPayload = { label?: string | null code?: string | null + display?: boolean | null } diff --git a/migrations/Version20260521092455.php b/migrations/Version20260521092455.php new file mode 100644 index 0000000..631c554 --- /dev/null +++ b/migrations/Version20260521092455.php @@ -0,0 +1,29 @@ +addSql('ALTER TABLE bovine_type ADD display BOOLEAN DEFAULT false NOT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE bovine_type DROP display'); + } +} diff --git a/src/Entity/BovineType.php b/src/Entity/BovineType.php index 507431f..a6181cb 100644 --- a/src/Entity/BovineType.php +++ b/src/Entity/BovineType.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace App\Entity; +use ApiPlatform\Doctrine\Orm\Filter\BooleanFilter; use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Metadata\ApiFilter; use ApiPlatform\Metadata\ApiResource; @@ -19,6 +20,7 @@ use Symfony\Component\Serializer\Attribute\Groups; 'label' => 'ipartial', 'code' => 'ipartial', ])] +#[ApiFilter(BooleanFilter::class, properties: ['display'])] #[ApiResource( operations: [ new Get( @@ -58,6 +60,15 @@ class BovineType #[Groups(['bovine-type:read', 'bovine-type:write', 'reception:read', 'reception-bovine:read', 'bovine:read', 'building_case:read'])] private ?string $code = null; + /** + * Détermine si le type bovin est proposé à la sélection lors d'une réception. + * Les types créés automatiquement par la synchro inventaire arrivent à false ; + * seul un admin peut les activer. + */ + #[ORM\Column(options: ['default' => false])] + #[Groups(['bovine-type:read', 'bovine-type:write'])] + private bool $display = false; + public function getId(): ?int { return $this->id; @@ -86,4 +97,16 @@ class BovineType return $this; } + + public function isDisplay(): bool + { + return $this->display; + } + + public function setDisplay(bool $display): static + { + $this->display = $display; + + return $this; + } }