Files
Ferme/frontend/components/reception/update-weight.vue

164 lines
4.7 KiB
Vue

<template>
<form>
<div class="grid grid-cols-3 gap-x-40 gap-y-8 mb-8">
<UiNumberInput
:key="weight.type"
:label="'POIDS'"
labelClass="font-bold uppercase text-xl "
v-model="weight.weight"
:disabled="!auth.isAdmin"
:min="0"
:max="48000"
wrapper-class="flex-col"
/>
<UiDateInput
label="Date pesée"
v-model="sharedWeightMeta.weighedAt"
:disabled="!auth.isAdmin"
/>
<UiNumberInput
label="Dsd"
class="col-start-2"
labelClass="font-bold uppercase"
v-model="sharedWeightMeta.dsd"
:disabled="!auth.isAdmin"
wrapper-class="flex-col"
/>
</div>
</form>
</template>
<script setup lang="ts">
import type {ReceptionFormWeight} from '~/services/dto/reception-data'
import {getReception} from '~/services/reception'
import {updateWeight} from "~/services/weight";
import {useAuthStore} from "~/stores/auth";
import {ref, watch} from "vue";
const props = defineProps<{
idReception: number
weightType: string
isValidate: boolean
}>()
const form = reactive({
weights: [
{id: 0, type: 'tare' as const, weight: 0, dsd: null, weighedAt: null},
{id: 0, type: 'gross' as const, weight: 0, dsd: null, weighedAt: null}
]
})
const idReception = props.idReception
const weightType = props.weightType
const auth = useAuthStore()
const weight = form.weights.find(w => w.type === weightType)
const initialWeight = ref<{ weight: number | null; dsd: number | null; weighedAt: string | null } | null>(null)
// DSD et date de pesée sont partagés entre tare et gross dans l'UI.
const sharedWeightMeta = reactive<{
dsd: number | string | null
weighedAt: string | null
}>({
dsd: null,
weighedAt: null
})
const normalizeMeta = () => {
const sharedDsd =
sharedWeightMeta.dsd === null || sharedWeightMeta.dsd === undefined || sharedWeightMeta.dsd === ''
? null
: Number(sharedWeightMeta.dsd)
const sharedWeighedAt =
sharedWeightMeta.weighedAt === null || sharedWeightMeta.weighedAt === undefined || sharedWeightMeta.weighedAt === ''
? null
: sharedWeightMeta.weighedAt
return {
dsd: Number.isFinite(sharedDsd) ? sharedDsd : null,
weighedAt: sharedWeighedAt
}
}
const hydrateFromReception = (reception: ReceptionFormWeight) => {
// On hydrate chaque ligne par son type (tare/gross), sans dépendre d'un index.
for (const receptionWeight of reception.weights) {
const formWeight = form.weights.find(weight => weight.type === receptionWeight.type)
if (formWeight) {
Object.assign(formWeight, receptionWeight)
}
}
// On récupère une valeur existante pour préremplir les champs partagés.
const weightWithMeta = reception.weights.find(weight =>
(weight.dsd !== null && weight.dsd !== undefined)
|| (weight.weighedAt !== null && weight.weighedAt !== undefined && weight.weighedAt !== '')
)
if (weightWithMeta) {
sharedWeightMeta.dsd = weightWithMeta.dsd ?? null
sharedWeightMeta.weighedAt = weightWithMeta.weighedAt ?? null
}
if (weight) {
const normalized = normalizeMeta()
initialWeight.value = {
weight: weight.weight ?? null,
dsd: normalized.dsd,
weighedAt: normalized.weighedAt
}
}
}
onMounted(async () => {
const reception = await getReception(idReception)
hydrateFromReception(reception)
})
watch(
() => props.isValidate,
async (val) => {
if (!val) return
await runValidate()
}
)
const hasChanged = (current: { weight: number | null; dsd: number | null; weighedAt: string | null }) => {
if (!initialWeight.value) {
return true
}
return (
(current.weight ?? null) !== (initialWeight.value.weight ?? null) ||
(current.dsd ?? null) !== (initialWeight.value.dsd ?? null) ||
(current.weighedAt ?? null) !== (initialWeight.value.weighedAt ?? null)
)
}
const runValidate = async () => {
if (!weight?.id) {
return
}
const normalized = normalizeMeta()
const current = {
weight: weight.weight ?? null,
dsd: normalized.dsd,
weighedAt: normalized.weighedAt
}
if (!hasChanged(current)) {
return
}
await updateWeight(weight.id, {
weight: current.weight,
dsd: current.dsd,
weighedAt: current.weighedAt
})
initialWeight.value = current
}
</script>