feat : Ajout de la sélection des bovins étape 3 d'une réception

This commit is contained in:
2026-02-05 09:08:30 +01:00
parent 81c2a5802b
commit 33563addbe
8 changed files with 164 additions and 52 deletions

View File

@@ -36,7 +36,7 @@
<script setup lang="ts">
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
import {getBovineTypeList} from "~/services/bovine-type";
import {RECEPTION_TYPE_CODES} from "~/utils/constants";
import {MERCHANDISE_TYPE_CODES, RECEPTION_TYPE_CODES} from "~/utils/constants";
import {useReceptionStore} from '~/stores/reception'
import {
createReceptionBovine,
@@ -55,6 +55,19 @@ const receptionId = computed(() => receptionStore.current?.id ?? null)
const receptionIri = computed(() =>
receptionId.value ? `/api/receptions/${receptionId.value}` : null
)
const toast = useToast()
const nuxtApp = useNuxtApp()
const i18n = nuxtApp.$i18n as { t: (key: string) => string } |
undefined
const t = (key: string) => (i18n?.t ? String(i18n.t(key)) : key)
const totalBovineQuantity = computed(() => {
const baseTotal = Object.values(bovineQuantities).reduce((sum, value) => {
const n = typeof value === 'number' ? value : 0
return sum + n
}, 0)
const other = typeof otherQuantity.value === 'number' ? otherQuantity.value : 0
return baseTotal + other
})
const loadBovineType = async () => {
isLoadingBovineType.value = true
try {
@@ -90,6 +103,13 @@ watch(
delete bovineQuantities[key]
}
Object.assign(bovineQuantities, selectionMap)
const existingOther = receptionStore.current?.bovineDetail
const parsedOther =
typeof existingOther === 'string' && existingOther.trim() !== ''
? Number(existingOther)
: 0
otherQuantity.value = Number.isFinite(parsedOther) ? parsedOther : 0
},
{immediate: true}
)
@@ -115,7 +135,7 @@ async function syncBovineSelections(receptionIri: string) {
}
if (selectedQuantity !== entry.quantity) {
await updateReceptionBovine(entry.id, { quantity: selectedQuantity })
await updateReceptionBovine(entry.id, {quantity: selectedQuantity})
existingMap.set(bovineTypeId, {
id: entry.id,
quantity: selectedQuantity
@@ -139,18 +159,44 @@ async function syncBovineSelections(receptionIri: string) {
})
}
}
const hasNegativeQuantity = computed(() => {
const anyNegativeInTypes =
Object.values(bovineQuantities).some((value) => {
return typeof value === 'number' && value < 0
})
const otherNegative =
typeof otherQuantity.value === 'number' &&
otherQuantity.value < 0
return anyNegativeInTypes || otherNegative
})
async function goNext() {
if (!receptionStore.current || !receptionIri.value) {
return
}
if (hasNegativeQuantity.value) {
toast.error({
title: 'Erreur',
message: ("La quantité de bovins ne peut pas être négative.")
})
return
}
// Le 52 à vérifier
if (totalBovineQuantity.value > 52) {
toast.error({
title: 'Erreur',
message: ('Le total des bovins ne peut pas dépasser 52.')
})
return
}
const nextStep = receptionStore.current.currentStep + 1
await syncBovineSelections(receptionIri.value)
await receptionStore.updateReception(receptionStore.current.id, {
merchandiseType: null,
merchandiseDetail: null,
bovineDetail: otherQuantity.value ? String(otherQuantity.value) : null,
currentStep: nextStep
})
}

View File

@@ -142,7 +142,8 @@ import type {DriverData} from '~/services/dto/driver-data'
import {getDriverList} from '~/services/driver'
import type {VehicleData} from '~/services/dto/vehicle-data'
import {getVehicleList} from '~/services/vehicle'
import {SUPLLIER_CODE} from "~/utils/constants";
import {RECEPTION_TYPE_CODES, SUPLLIER_CODE} from "~/utils/constants";
import {deleteReceptionBovine, getReceptionBovineList} from "~/services/reception-bovine";
type ReceptionFormData = {
licensePlate: string
@@ -221,6 +222,16 @@ const filteredVehicles = computed<VehicleData[]>(() => {
(!form.truckId || String(vehicle.truck?.id) === form.truckId)
)
})
const selectedReceptionType = computed(() =>
receptionTypes.value.find((type) => String(type.id) === form.receptionTypeId) ?? null
)
const clearReceptionBovines = async (receptionIri: string) => {
const existing = await getReceptionBovineList(receptionIri)
for (const selection of existing) {
await deleteReceptionBovine(selection.id)
}
}
// Hydrate le formulaire depuis la réception en cours
watch(
@@ -460,6 +471,9 @@ async function validate() {
const normalizedTruckId = form.truckId.trim()
const normalizedCarrierId = form.carrierId.trim()
const normalizedDriverId = form.driverId.trim()
const previousTypeCode = receptionStore.current.receptionType?.code ?? null
const nextTypeCode = selectedReceptionType.value?.code ?? null
const receptionIri = `/api/receptions/${receptionStore.current.id}`
const receptionTypeIri = normalizedReceptionTypeId
? `/api/reception_types/${normalizedReceptionTypeId}`
: null
@@ -508,7 +522,12 @@ async function validate() {
}
return
}
if (
previousTypeCode === RECEPTION_TYPE_CODES.BOVINS &&
nextTypeCode === RECEPTION_TYPE_CODES.MERCHANDISES
) {
await clearReceptionBovines(receptionIri)
}
const nextStep = receptionStore.current.currentStep + 1
await receptionStore.updateReception(receptionStore.current.id, {
currentStep: nextStep,

View File

@@ -192,6 +192,7 @@ async function goNext() {
buildings: isGranule.value
? []
: selectedBuildingIds.value.map((id) => `/api/buildings/${id}`),
bovineDetail: null,
bovinesTypes: null,
currentStep: nextStep
})