fix : page de modification reception qui crash en prod

This commit is contained in:
tristan
2026-02-26 10:28:00 +01:00
parent c48cc477da
commit 59d76c5f14
4 changed files with 236 additions and 57 deletions
+102 -22
View File
@@ -172,13 +172,13 @@
/>
<update-merchandise
v-show="activeTab === 'merchandise' && isMerchandise"
v-if="activeTab === 'merchandise' && isMerchandise"
v-model="merchandiseForm"
:isAdmin="auth.isAdmin"
/>
<update-bovin
v-show="activeTab === 'merchandise' && !isMerchandise"
v-if="activeTab === 'merchandise' && !isMerchandise"
v-model="bovineEntries"
v-model:otherQuantity="bovineOtherQuantity"
:isAdmin="auth.isAdmin"
@@ -279,9 +279,25 @@ const isLoadingVehicles = ref(false)
const formIsLoading = ref(false)
const isMerchandise = ref(false)
const isHydrating = ref(false)
const vehicleSyncLock = ref(false)
const idReception = Number(route.params.id)
function runWithVehicleSyncLock(mutator: () => void) {
if (vehicleSyncLock.value) {
return
}
vehicleSyncLock.value = true
try {
mutator()
} finally {
queueMicrotask(() => {
vehicleSyncLock.value = false
})
}
}
const form = reactive<ReceptionFormData>({
identificationNumber: null,
licensePlate: '',
@@ -581,8 +597,16 @@ async function saveWeightEntry(entry: WeightEntryData) {
return
}
// Fallback: if id is missing in local state, reuse existing weight by type.
const reception = await getReception(idReception)
const existingEntry = reception?.weights?.find((weight) => weight.type === entry.type) ?? null
if (existingEntry?.id) {
await updateWeight(existingEntry.id, payload)
return
}
await createWeight({
reception: `api/receptions/${idReception}`,
reception: `/api/receptions/${idReception}`,
...payload
})
}
@@ -785,8 +809,11 @@ async function validate() {
})
}
const refreshedReception = await getReception(idReception)
hydrateFromReception(refreshedReception)
// Évite une réhydratation complète après save (source de cascades de watchers).
// On recharge uniquement les bovins quand on est en mode bovins.
if (!isMerchandise.value) {
await loadBovineEntries(idReception)
}
return
}
@@ -809,12 +836,20 @@ onMounted(async () => {
watch(
() => [form.supplierId, form.addressId, suppliers.value],
() => {
if (isHydrating.value) {
return
}
if (!form.supplierId) {
form.addressId = ''
if (form.addressId !== '') {
form.addressId = ''
}
return
}
if (!form.addressId && supplierAddresses.value.length === 1) {
form.addressId = String(supplierAddresses.value[0].id)
const nextAddressId = String(supplierAddresses.value[0].id)
if (form.addressId !== nextAddressId) {
form.addressId = nextAddressId
}
return
}
if (!form.addressId) {
@@ -825,9 +860,14 @@ watch(
)
if (!matches) {
if (supplierAddresses.value.length === 1) {
form.addressId = String(supplierAddresses.value[0].id)
const nextAddressId = String(supplierAddresses.value[0].id)
if (form.addressId !== nextAddressId) {
form.addressId = nextAddressId
}
} else {
form.addressId = ''
if (form.addressId !== '') {
form.addressId = ''
}
}
}
},
@@ -837,24 +877,36 @@ watch(
watch(
() => form.carrierId,
() => {
if (isHydrating.value) {
if (isHydrating.value || vehicleSyncLock.value) {
return
}
if (!form.carrierId && idReception == null) {
form.driverId = ''
form.vehicleId = ''
runWithVehicleSyncLock(() => {
form.driverId = ''
form.vehicleId = ''
})
return
}
if (!isLiotCarrier.value && idReception == null) {
form.driverId = ''
form.vehicleId = ''
runWithVehicleSyncLock(() => {
form.driverId = ''
form.vehicleId = ''
})
return
}
if (filteredDrivers.value.length === 1) {
form.driverId = String(filteredDrivers.value[0].id)
const nextDriverId = String(filteredDrivers.value[0].id)
if (form.driverId !== nextDriverId) {
form.driverId = nextDriverId
}
}
if (filteredVehicles.value.length === 1) {
form.vehicleId = String(filteredVehicles.value[0].id)
const nextVehicleId = String(filteredVehicles.value[0].id)
if (form.vehicleId !== nextVehicleId) {
runWithVehicleSyncLock(() => {
form.vehicleId = nextVehicleId
})
}
}
},
{ immediate: true }
@@ -863,11 +915,19 @@ watch(
watch(
() => [form.truckId, form.carrierId, vehicles.value],
() => {
if (isHydrating.value || vehicleSyncLock.value) {
return
}
if (!isLiotCarrier.value) {
return
}
if (filteredVehicles.value.length === 1) {
form.vehicleId = String(filteredVehicles.value[0].id)
const nextVehicleId = String(filteredVehicles.value[0].id)
if (form.vehicleId !== nextVehicleId) {
runWithVehicleSyncLock(() => {
form.vehicleId = nextVehicleId
})
}
return
}
if (!form.vehicleId) {
@@ -877,7 +937,11 @@ watch(
(vehicle) => String(vehicle.id) === form.vehicleId
)
if (!matches) {
form.vehicleId = ''
if (form.vehicleId !== '') {
runWithVehicleSyncLock(() => {
form.vehicleId = ''
})
}
}
},
{ immediate: true }
@@ -886,6 +950,9 @@ watch(
watch(
() => [form.vehicleId, form.carrierId, vehicles.value],
() => {
if (vehicleSyncLock.value) {
return
}
if (!isLiotCarrier.value) {
return
}
@@ -895,9 +962,11 @@ watch(
const selected = filteredVehicles.value.find(
(vehicle) => String(vehicle.id) === form.vehicleId
)
if (selected) {
form.licensePlate = selected.plate
allowAnyLicensePlate.value = false
if (selected && form.licensePlate !== selected.plate) {
runWithVehicleSyncLock(() => {
form.licensePlate = selected.plate
allowAnyLicensePlate.value = false
})
}
}
)
@@ -905,6 +974,12 @@ watch(
watch(
() => [form.licensePlate, form.carrierId, vehicles.value],
() => {
if (vehicleSyncLock.value) {
return
}
if (isHydrating.value) {
return
}
if (!isLiotCarrier.value || form.vehicleId) {
return
}
@@ -912,7 +987,12 @@ watch(
(vehicle) => vehicle.plate === form.licensePlate
)
if (match) {
form.vehicleId = String(match.id)
const nextVehicleId = String(match.id)
if (form.vehicleId !== nextVehicleId) {
runWithVehicleSyncLock(() => {
form.vehicleId = nextVehicleId
})
}
}
}
)