- Ajout page infrastructure/bovine avec CRUD - Refacto BuildingCase (suppression Statut, simplification) - Commande EnrichBovinesCommand pour enrichir les données bovins - 4 migrations Doctrine - Mise à jour composables shipment/weighing - Mise à jour README et CHANGELOG Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
181 lines
5.6 KiB
Vue
181 lines
5.6 KiB
Vue
<template>
|
|
<form :class="{ submitted }" @submit.prevent="validate">
|
|
<div class="flex items-center relative">
|
|
<div class="flex flex-row absolute -left-[60px]">
|
|
<Icon
|
|
@click="goBack"
|
|
name="gg:arrow-left-o"
|
|
size="40"
|
|
class="cursor-pointer text-primary-500"
|
|
/>
|
|
</div>
|
|
<h1 class="text-3xl text-primary-500 font-bold uppercase">
|
|
{{ isEdit ? 'Modification d\'un bovin' : 'Ajout d\'un bovin' }}
|
|
</h1>
|
|
</div>
|
|
|
|
<div class="flex flex-cols-3 justify-between mb-11 pt-7">
|
|
<UiTextInput
|
|
id="bovine-national-number"
|
|
v-model="form.nationalNumber"
|
|
label="Numéro national"
|
|
:disabled="!auth.isAdmin || isLoading"
|
|
wrapper-class="w-[280px]"
|
|
required
|
|
/>
|
|
<UiNumberInput
|
|
id="bovine-received-weight"
|
|
v-model="form.receivedWeight"
|
|
label="Poids à l'arrivée (kg)"
|
|
:min="0"
|
|
:disabled="!auth.isAdmin || isLoading"
|
|
wrapper-class="w-[280px] flex-col"
|
|
label-class="font-bold uppercase"
|
|
/>
|
|
<UiDateInput
|
|
id="bovine-arrival-date"
|
|
v-model="form.arrivalDate"
|
|
label="Date d'arrivée"
|
|
:disabled="!auth.isAdmin || isLoading"
|
|
wrapper-class="w-[280px]"
|
|
/>
|
|
</div>
|
|
<div class="flex flex-cols-3 justify-between mb-11">
|
|
<UiSelect
|
|
id="bovine-supplier"
|
|
v-model="form.supplierId"
|
|
label="Vendeur"
|
|
:options="supplierOptions"
|
|
:loading="isLoadingSuppliers"
|
|
:disabled="!auth.isAdmin || isLoading"
|
|
wrapper-class="w-[280px]"
|
|
/>
|
|
<div class="w-[280px]" />
|
|
<div class="w-[280px]" />
|
|
</div>
|
|
|
|
<div class="flex items-center justify-center">
|
|
<UiButton
|
|
type="submit"
|
|
:disabled="!auth.isAdmin || isLoading"
|
|
class="inline-flex mb-28 items-center justify-center text-xl min-w-[194px] gap-2 text-white uppercase bg-primary-500 h-[50px] rounded hover:opacity-80 justify-self-end"
|
|
@click="submitted = true"
|
|
>
|
|
<Icon :name="isEdit ? '' : 'mdi:plus'" size="28" />
|
|
{{ isEdit ? 'Valider' : 'Ajouter' }}
|
|
</UiButton>
|
|
</div>
|
|
</form>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { createBovine, getBovine, updateBovine } from '~/services/bovine'
|
|
import type { BovinePayload } from '~/services/dto/bovine-data'
|
|
import type { SupplierData } from '~/services/dto/supplier-data'
|
|
import { getSupplierList } from '~/services/supplier'
|
|
import { useAuthStore } from '~/stores/auth'
|
|
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
const auth = useAuthStore()
|
|
|
|
const caseId = computed(() => {
|
|
const raw = Number(route.query.caseId)
|
|
return Number.isFinite(raw) && raw > 0 ? raw : null
|
|
})
|
|
|
|
const bovineId = computed(() => {
|
|
const raw = Number(route.query.id)
|
|
return Number.isFinite(raw) && raw > 0 ? raw : null
|
|
})
|
|
|
|
const isEdit = computed(() => bovineId.value !== null)
|
|
|
|
const form = reactive<{
|
|
nationalNumber: string
|
|
receivedWeight: number | null
|
|
arrivalDate: string | null
|
|
supplierId: string
|
|
}>({
|
|
nationalNumber: '',
|
|
receivedWeight: null,
|
|
arrivalDate: null,
|
|
supplierId: ''
|
|
})
|
|
|
|
const isLoading = ref(false)
|
|
const submitted = ref(false)
|
|
const suppliers = ref<SupplierData[]>([])
|
|
const isLoadingSuppliers = ref(false)
|
|
|
|
const supplierOptions = computed(() =>
|
|
suppliers.value.map(s => ({ value: String(s.id), label: s.name }))
|
|
)
|
|
|
|
const backRoute = computed(() => ({
|
|
path: '/infrastructure/case',
|
|
query: caseId.value ? { id: String(caseId.value) } : {}
|
|
}))
|
|
|
|
const goBack = () => {
|
|
router.push(backRoute.value)
|
|
}
|
|
|
|
const loadSuppliers = async () => {
|
|
isLoadingSuppliers.value = true
|
|
try {
|
|
suppliers.value = await getSupplierList()
|
|
} finally {
|
|
isLoadingSuppliers.value = false
|
|
}
|
|
}
|
|
|
|
const hydrate = async () => {
|
|
if (!isEdit.value || bovineId.value === null) {
|
|
return
|
|
}
|
|
isLoading.value = true
|
|
try {
|
|
const bovine = await getBovine(bovineId.value)
|
|
form.nationalNumber = bovine.nationalNumber ?? ''
|
|
form.receivedWeight = bovine.receivedWeight ?? null
|
|
form.arrivalDate = bovine.arrivalDate ?? null
|
|
if (bovine.supplier) {
|
|
const supplierId = bovine.supplier.replace(/.*\//, '')
|
|
form.supplierId = supplierId
|
|
}
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
const validate = async () => {
|
|
if (isLoading.value || !auth.isAdmin) return
|
|
if (!caseId.value) return
|
|
if (!form.nationalNumber.trim()) return
|
|
|
|
const payload: BovinePayload = {
|
|
nationalNumber: form.nationalNumber.trim(),
|
|
receivedWeight: form.receivedWeight,
|
|
arrivalDate: form.arrivalDate,
|
|
buildingCase: `/api/building_cases/${caseId.value}`,
|
|
supplier: form.supplierId ? `/api/suppliers/${form.supplierId}` : null
|
|
}
|
|
|
|
isLoading.value = true
|
|
try {
|
|
if (isEdit.value && bovineId.value !== null) {
|
|
await updateBovine(bovineId.value, payload)
|
|
} else {
|
|
await createBovine(payload)
|
|
}
|
|
router.push(backRoute.value)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(loadSuppliers)
|
|
watch(bovineId, hydrate, { immediate: true })
|
|
</script>
|