fix : corrections diverses
This commit is contained in:
@@ -29,7 +29,7 @@
|
|||||||
<button
|
<button
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
@click="goNext"
|
@click="goNext"
|
||||||
>Peser
|
>Valider
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -119,7 +119,7 @@
|
|||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
|
||||||
>Peser
|
>Valider
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@@ -342,7 +342,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
||||||
watch(
|
watch(
|
||||||
() => [form.supplierId, suppliers.value],
|
() => [form.supplierId, form.addressId, suppliers.value],
|
||||||
() => {
|
() => {
|
||||||
if (!form.supplierId) {
|
if (!form.supplierId) {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
@@ -359,8 +359,12 @@ watch(
|
|||||||
(address) => String(address.id) === form.addressId
|
(address) => String(address.id) === form.addressId
|
||||||
)
|
)
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
|
if (supplierAddresses.value.length === 1) {
|
||||||
|
form.addressId = String(supplierAddresses.value[0].id)
|
||||||
|
} else {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{immediate: true}
|
{immediate: true}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
<button
|
<button
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
@click="goNext"
|
@click="goNext"
|
||||||
>Peser
|
>Valider
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
v-if="displayWeight !== null && !showGenerateReceipt"
|
v-if="displayWeight !== null && !showGenerateReceipt"
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] ml-4"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] ml-4"
|
||||||
@click="saveWeight"
|
@click="saveWeight"
|
||||||
>Valider la pesée</button>
|
>Valider</button>
|
||||||
<button
|
<button
|
||||||
v-if="showGenerateReceipt"
|
v-if="showGenerateReceipt"
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] ml-4"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] ml-4"
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import {computed, onMounted} from 'vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useWeighing } from '~/composables/useWeighing'
|
import { useWeighing } from '~/composables/useWeighing'
|
||||||
import { usePdfPrinter } from '~/composables/usePdfPrinter'
|
import { usePdfPrinter } from '~/composables/usePdfPrinter'
|
||||||
@@ -94,7 +94,7 @@ const printReceipt = async () => {
|
|||||||
|
|
||||||
// Récupère le poids dès l'arrivée sur l'écran
|
// Récupère le poids dès l'arrivée sur l'écran
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (false === displayWeight.value) {
|
if (displayWeight.value === null) {
|
||||||
fetchWeight()
|
fetchWeight()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
v-if="auth.isAdmin"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
:disabled="!auth.isAdmin"
|
:disabled="!auth.isAdmin"
|
||||||
|
|||||||
@@ -1,27 +1,42 @@
|
|||||||
<template>
|
<template>
|
||||||
<form @submit.prevent="validate">
|
<form @submit.prevent="validate">
|
||||||
|
<div class="grid grid-cols-2 gap-x-40 gap-y-8 mb-8">
|
||||||
<div class="grid grid-cols-2 gap-x-40 gap-y-8 mb-16">
|
<UiTextInput
|
||||||
|
label="Dsd"
|
||||||
|
class="col-start-2"
|
||||||
|
v-model="form.weights[0].dsd"
|
||||||
|
:disabled="!auth.isAdmin"
|
||||||
|
/>
|
||||||
|
<UiDateInput
|
||||||
|
label="Date pesée"
|
||||||
|
v-model="form.weights[0].weighedAt"
|
||||||
|
:disabled="!auth.isAdmin"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-x-40 mb-16">
|
||||||
<UiNumberInput
|
<UiNumberInput
|
||||||
label="Pesée à vide"
|
label="Pesée à vide"
|
||||||
|
labelClass="font-bold uppercase text-xl"
|
||||||
v-model="form.weights[0].weight"
|
v-model="form.weights[0].weight"
|
||||||
|
wrapper-class="col-start-1 row-start-1"
|
||||||
:disabled="!auth.isAdmin"
|
:disabled="!auth.isAdmin"
|
||||||
:min="0"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<UiNumberInput
|
<UiNumberInput
|
||||||
label="Pesée à plein"
|
label="Pesée à plein"
|
||||||
|
labelClass="font-bold uppercase text-xl"
|
||||||
v-model="form.weights[1].weight"
|
v-model="form.weights[1].weight"
|
||||||
|
wrapper-class="col-start-2 row-start-1"
|
||||||
:disabled="!auth.isAdmin"
|
:disabled="!auth.isAdmin"
|
||||||
:min="0"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<button
|
<button
|
||||||
|
v-if="auth.isAdmin"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
:disabled="!auth.isAdmin"
|
|
||||||
>
|
>
|
||||||
Valider
|
Valider
|
||||||
</button>
|
</button>
|
||||||
@@ -45,8 +60,8 @@ const auth = useAuthStore()
|
|||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
weights: [
|
weights: [
|
||||||
{ id: 0, type: 'tare' as const, weight: 0 },
|
{id: 0, type: 'tare' as const, weight: 0, dsd: null, weighedAt: null},
|
||||||
{ id: 0, type: 'gross' as const, weight: 0 }
|
{id: 0, type: 'gross' as const, weight: 0, dsd: null, weighedAt: null}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -54,8 +69,8 @@ const hydrateFromReception = (reception: ReceptionFormWeight) => {
|
|||||||
const tare = reception.weights.find(weight => weight.type === 'tare')
|
const tare = reception.weights.find(weight => weight.type === 'tare')
|
||||||
const gross = reception.weights.find(weight => weight.type === 'gross')
|
const gross = reception.weights.find(weight => weight.type === 'gross')
|
||||||
|
|
||||||
if (tare) form.weights[0] = { ...tare }
|
if (tare) form.weights[0] = {...form.weights[0], ...tare}
|
||||||
if (gross) form.weights[1] = { ...gross }
|
if (gross) form.weights[1] = {...form.weights[1], ...gross}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -64,11 +79,24 @@ onMounted(async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function validate() {
|
async function validate() {
|
||||||
|
const sharedDsd =
|
||||||
|
form.weights[0].dsd === null || form.weights[0].dsd === undefined || form.weights[0].dsd === ''
|
||||||
|
? null
|
||||||
|
: Number(form.weights[0].dsd)
|
||||||
|
const sharedWeighedAt =
|
||||||
|
form.weights[0].weighedAt === null || form.weights[0].weighedAt === undefined || form.weights[0].weighedAt === ''
|
||||||
|
? null
|
||||||
|
: form.weights[0].weighedAt
|
||||||
|
|
||||||
for (const weight of form.weights) {
|
for (const weight of form.weights) {
|
||||||
if (weight.id) {
|
if (weight.id) {
|
||||||
await updateWeight(weight.id, {weight: weight.weight})
|
await updateWeight(weight.id, {
|
||||||
|
weight: weight.weight,
|
||||||
|
dsd: Number.isFinite(sharedDsd) ? sharedDsd : null,
|
||||||
|
weighedAt: sharedWeighedAt
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -23,14 +23,14 @@
|
|||||||
/>
|
/>
|
||||||
<!-- Type d'expédition -->
|
<!-- Type d'expédition -->
|
||||||
<div class="col-start-1 row-start-4">
|
<div class="col-start-1 row-start-4">
|
||||||
<label class="font-bold uppercase text-xl mb-2 block">
|
<label class="font-bold uppercase text-xl mb-2">
|
||||||
Type d'expédition
|
Type d'expédition
|
||||||
</label>
|
</label>
|
||||||
<div class="grid grid-cols-2 gap-x-8">
|
<div class="grid grid-cols-2 gap-x-8">
|
||||||
<div
|
<div
|
||||||
v-for="type in bovineShipment"
|
v-for="type in bovineShipment"
|
||||||
:key="type.id"
|
:key="type.id"
|
||||||
class="mt-8 flex flex-row gap-6"
|
class="mt-2 flex flex-row gap-6"
|
||||||
>
|
>
|
||||||
<UiNumberInput
|
<UiNumberInput
|
||||||
:label="type.label"
|
:label="type.label"
|
||||||
@@ -344,7 +344,7 @@ watch(
|
|||||||
)
|
)
|
||||||
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
||||||
watch(
|
watch(
|
||||||
() => [form.customerId, customers.value],
|
() => [form.customerId, form.addressId, customers.value],
|
||||||
() => {
|
() => {
|
||||||
if (!form.customerId) {
|
if (!form.customerId) {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
@@ -361,8 +361,12 @@ watch(
|
|||||||
(address) => String(address.id) === form.addressId
|
(address) => String(address.id) === form.addressId
|
||||||
)
|
)
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
|
if (customerAddresses.value.length === 1) {
|
||||||
|
form.addressId = String(customerAddresses.value[0].id)
|
||||||
|
} else {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{immediate: true}
|
{immediate: true}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<label
|
<label
|
||||||
v-if="label"
|
v-if="label"
|
||||||
:for="id"
|
:for="id"
|
||||||
class="text-xl text-bold flex items-center"
|
class="text-xl flex items-center"
|
||||||
:class="labelClass"
|
:class="labelClass"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
:step="step"
|
:step="step"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
class="border-b border-black text-xl bg-transparent w-12"
|
class="border-b border-black text-xl bg-transparent w-16"
|
||||||
:class="[
|
:class="[
|
||||||
isEmpty ? 'text-neutral-400' : 'text-black',
|
isEmpty ? 'text-neutral-400' : 'text-black',
|
||||||
disabled ? 'cursor-not-allowed' : 'cursor-text',
|
disabled ? 'cursor-not-allowed' : 'cursor-text',
|
||||||
|
|||||||
@@ -24,17 +24,41 @@
|
|||||||
<aside class="bg-primary-500 text-white min-h-0 flex flex-col justify-between">
|
<aside class="bg-primary-500 text-white min-h-0 flex flex-col justify-between">
|
||||||
<div class="flex flex-col gap-4 p-4 font-bold text-xl">
|
<div class="flex flex-col gap-4 p-4 font-bold text-xl">
|
||||||
<!-- Liste des liens à ajouter ci-dessous -->
|
<!-- Liste des liens à ajouter ci-dessous -->
|
||||||
<NuxtLink to="/admin/dashboard">
|
<NuxtLink
|
||||||
|
to="/admin/dashboard"
|
||||||
|
custom v-slot="{ href, navigate, isExactActive }">
|
||||||
|
<a :href="href"
|
||||||
|
@click="navigate"
|
||||||
|
:class="isExactActive ? 'opacity-100' : 'opacity-50'">
|
||||||
Tableau de bord
|
Tableau de bord
|
||||||
|
</a>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/admin/supplier/supplier-list">
|
<NuxtLink
|
||||||
|
to="/admin/supplier/supplier-list"
|
||||||
|
custom v-slot="{ href, navigate }">
|
||||||
|
<a :href="href"
|
||||||
|
@click="navigate"
|
||||||
|
:class="route.path.startsWith('/admin/supplier') ? 'opacity-100' : 'opacity-50'">
|
||||||
Fournisseur
|
Fournisseur
|
||||||
|
</a>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/admin/carrier/carrier-list">
|
<NuxtLink
|
||||||
|
to="/admin/carrier/carrier-list"
|
||||||
|
custom v-slot="{ href, navigate }">
|
||||||
|
<a :href="href"
|
||||||
|
@click="navigate"
|
||||||
|
:class="route.path.startsWith('/admin/carrier') ? 'opacity-100' : 'opacity-50'">
|
||||||
Transporteur
|
Transporteur
|
||||||
|
</a>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/admin/user/list">
|
<NuxtLink to="/admin/user/list" custom v-slot="{ href, navigate }">
|
||||||
|
<a
|
||||||
|
:href="href"
|
||||||
|
@click="navigate"
|
||||||
|
:class="route.path.startsWith('/admin/user') ? 'opacity-100' : 'opacity-50'"
|
||||||
|
>
|
||||||
Utilisateurs
|
Utilisateurs
|
||||||
|
</a>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/admin/customer/customer-list">
|
<NuxtLink to="/admin/customer/customer-list">
|
||||||
Client
|
Client
|
||||||
@@ -42,13 +66,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<p class="font-bold text-white text-left">v{{ version }}</p>
|
|
||||||
<button
|
<button
|
||||||
@click="handleLogout"
|
@click="handleLogout"
|
||||||
class="w-full bg-red-600 hover:bg-red-700 py-2 rounded font-bold"
|
class="w-full bg-red-600 hover:bg-red-700 py-2 rounded font-bold"
|
||||||
>
|
>
|
||||||
Déconnexion
|
Déconnexion
|
||||||
</button>
|
</button>
|
||||||
|
<p class="font-bold text-white text-center pt-2">
|
||||||
|
v{{ version }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
@@ -67,6 +94,8 @@ import {useAuthStore} from '~/stores/auth'
|
|||||||
|
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
const {version} = useAppVersion()
|
const {version} = useAppVersion()
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
try {
|
try {
|
||||||
await auth.logout()
|
await auth.logout()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="min-h-screen bg-white text-neutral-900">
|
<div class="min-h-screen text-neutral-900 grid grid-rows-[85px,1fr]">
|
||||||
<header class="w-full border-b border-neutral-200 bg-primary-500">
|
<header class="w-full border-b border-neutral-200 bg-primary-500">
|
||||||
<div class="flex w-full items-center justify-center px-6 py-4">
|
<div class="flex w-full items-center justify-center px-6 py-4">
|
||||||
<button
|
<button
|
||||||
@@ -21,12 +21,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
to="/admin/dashboard" custom v-slot="{ href, navigate, isActive }"
|
to="/admin/dashboard" custom v-slot="{ href, navigate, isExactActive }"
|
||||||
v-if="auth.isAdmin"
|
v-if="auth.isAdmin"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
:href="href"
|
:href="href"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
|
:class="isExactActive ? 'opacity-100' : 'opacity-50'"
|
||||||
>
|
>
|
||||||
Admin
|
Admin
|
||||||
</a>
|
</a>
|
||||||
@@ -100,7 +101,7 @@
|
|||||||
</aside>
|
</aside>
|
||||||
</transition>
|
</transition>
|
||||||
</header>
|
</header>
|
||||||
<main class="mx-auto w-full max-w-[1280px] pb-0">
|
<main class="mx-auto w-full max-w-[1280px]">
|
||||||
<slot/>
|
<slot/>
|
||||||
</main>
|
</main>
|
||||||
<footer class="w-full mt-8 bg-primary-500 p-6">
|
<footer class="w-full mt-8 bg-primary-500 p-6">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<form @submit.prevent="validate">
|
<form @submit.prevent="validate">
|
||||||
<div class="flex items-center justify-between gap-10">
|
<div class="flex items-center justify-between">
|
||||||
<h1 class="text-3xl font-bold uppercase">
|
<h1 class="text-3xl font-bold uppercase">
|
||||||
{{ supplierId ? "Modifications du fournisseur" : "Ajout d'un fournisseur" }}
|
{{ supplierId ? "Modifications du fournisseur" : "Ajout d'un fournisseur" }}
|
||||||
</h1>
|
</h1>
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-y-16 gap-x-12 mb-10 py-12 border-b border-black ">
|
<div class="grid grid-cols-2 gap-y-8 gap-x-80 mb-10 py-12">
|
||||||
<UiTextInput id="supplier-name" v-model="form.name" label="Nom du fournisseur" :disabled="!auth.isAdmin"/>
|
<UiTextInput id="supplier-name" v-model="form.name" label="Nom du fournisseur" :disabled="!auth.isAdmin"/>
|
||||||
<UiTextInput id="supplier-email" v-model="form.email" label="Email" :disabled="!auth.isAdmin"/>
|
<UiTextInput id="supplier-email" v-model="form.email" label="Email" :disabled="!auth.isAdmin"/>
|
||||||
<UiTextInput id="supplier-phone" v-model="form.phone" label="Téléphone" :disabled="!auth.isAdmin"/>
|
<UiTextInput id="supplier-phone" v-model="form.phone" label="Téléphone" :disabled="!auth.isAdmin"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between mb-4 py-6 border-t border-black"></div>
|
<div class="mx-24 mb-4 py-6 border-t border-black"></div>
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<h2 class="text-3xl font-bold uppercase">Adresses fournisseur</h2>
|
<h2 class="text-3xl font-bold uppercase">Adresses fournisseur</h2>
|
||||||
<button
|
<button
|
||||||
@@ -179,14 +179,17 @@ async function validate() {
|
|||||||
email,
|
email,
|
||||||
phone,
|
phone,
|
||||||
}
|
}
|
||||||
|
let targetId: number | null = null
|
||||||
|
|
||||||
if (supplierId.value !== null) {
|
if (supplierId.value !== null) {
|
||||||
await updateSupplier(supplierId.value, supplierPayload)
|
await updateSupplier(supplierId.value, supplierPayload)
|
||||||
|
targetId = supplierId.value
|
||||||
} else {
|
} else {
|
||||||
await createSupplier(supplierPayload)
|
const created = await createSupplier(supplierPayload)
|
||||||
|
targetId = created.id
|
||||||
}
|
}
|
||||||
|
|
||||||
await router.push("/admin/supplier/supplier-list")
|
await router.push(`/admin/supplier/${targetId}`)
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h1 class="text-3xl font-bold uppercase">Fournisseurs</h1>
|
<h1 class="text-3xl font-bold uppercase">Liste des fournisseurs</h1>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
to="/admin/supplier"
|
to="/admin/supplier"
|
||||||
class="flex items-center justify-center text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
class="flex items-center justify-center text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ definePageMeta({
|
|||||||
import {computed, reactive, ref, watch} from 'vue'
|
import {computed, reactive, ref, watch} from 'vue'
|
||||||
import {ROLE} from '~/utils/constants'
|
import {ROLE} from '~/utils/constants'
|
||||||
import {createUser, updateUser, getUser} from '~/services/auth'
|
import {createUser, updateUser, getUser} from '~/services/auth'
|
||||||
import type {UserData, UserFormData} from '~/services/dto/user-data'
|
import type {UserData, UserFormData, UserPayload} from '~/services/dto/user-data'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -105,10 +105,12 @@ async function validate() {
|
|||||||
const normalizedRole = form.role.trim()
|
const normalizedRole = form.role.trim()
|
||||||
const normalizedPassword = form.password.trim()
|
const normalizedPassword = form.password.trim()
|
||||||
|
|
||||||
const basePayload = {
|
const basePayload: UserPayload = {
|
||||||
username: normalizedUsername,
|
username: normalizedUsername,
|
||||||
roles: normalizedRole ? [normalizedRole] : undefined,
|
roles: normalizedRole ? [normalizedRole] : undefined,
|
||||||
password: normalizedPassword || undefined
|
}
|
||||||
|
if (normalizedPassword) {
|
||||||
|
basePayload.password = normalizedPassword
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userId.value) {
|
if (userId.value) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between h-[52px] mb-[80px]">
|
<div class="flex justify-between h-[52px] mt-6 mb-[80px]">
|
||||||
<div class="flex flex-1 mr-16">
|
<div class="flex flex-1 mr-16">
|
||||||
<UiStepper
|
<UiStepper
|
||||||
:labels="RECEPTION_STEP_LABELS"
|
:labels="RECEPTION_STEP_LABELS"
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<form @submit.prevent="validate">
|
<form @submit.prevent="validate">
|
||||||
<div class="flex items-center justify-between mt-8 mb-8 ">
|
<div class="flex items-center justify-between mt-12 mb-8 ">
|
||||||
<h1 class="font-bold text-5xl uppercase">Réception {{ receptionLoad?.identificationNumber }}</h1>
|
<h1 class="font-bold text-5xl uppercase">Réception {{ receptionLoad?.identificationNumber }}</h1>
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
|
|
||||||
:disabled="!auth.isAdmin"
|
|
||||||
>Enregistrer
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 items-start gap-y-8 gap-x-40 mb-16">
|
<div class="grid grid-cols-2 items-start gap-y-8 gap-x-40 mb-12">
|
||||||
<!-- Nom de l'utilisateur -->
|
<!-- Nom de l'utilisateur -->
|
||||||
<UiSelect
|
<UiSelect
|
||||||
id="reception-user"
|
id="reception-user"
|
||||||
@@ -120,18 +114,41 @@
|
|||||||
wrapper-class="col-start-2 row-start-4"
|
wrapper-class="col-start-2 row-start-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 items-start gap-y-8 gap-x-40 mb-16">
|
<div class="flex justify-center mb-2">
|
||||||
<h1 class="font-bold text-5xl uppercase col-start-1 row-start-1" @click="isBtWeight = true" >pesées</h1>
|
<button
|
||||||
<h1 class="font-bold text-5xl uppercase col-start-2 row-start-1" @click="isBtWeight = false">{{isMerchandise ? "Marchandises" : "Bovins"}}</h1>
|
v-if="auth.isAdmin"
|
||||||
|
type="submit"
|
||||||
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] mb-16"
|
||||||
|
|
||||||
|
>
|
||||||
|
Enregistrer
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex justify-evenly gap-y-8 gap-x-40 mb-8 border-b border-slate-400">
|
||||||
|
<h1
|
||||||
|
class="font-bold text-3xl uppercase col-start-1 row-start-1 cursor-pointer"
|
||||||
|
:class="activeTab === 'weights' ? 'underline' : ''"
|
||||||
|
@click="activeTab = 'weights'"
|
||||||
|
>
|
||||||
|
pesées
|
||||||
|
</h1>
|
||||||
|
<h1
|
||||||
|
class="font-bold text-3xl uppercase col-start-2 row-start-1 cursor-pointer"
|
||||||
|
:class="activeTab === 'merchandise' ? 'underline' : ''"
|
||||||
|
@click="activeTab = 'merchandise'"
|
||||||
|
>
|
||||||
|
{{ isMerchandise ? "Marchandise" : "Bovins" }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
<update-weight
|
<update-weight
|
||||||
v-if="isBtWeight"
|
v-if="activeTab === 'weights'"
|
||||||
:idReception="idReception"
|
:idReception="idReception"
|
||||||
:disabled="!auth.isAdmin"
|
:disabled="!auth.isAdmin"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<update-merchandise
|
<update-merchandise
|
||||||
v-else-if="isMerchandise"
|
v-else-if="activeTab === 'merchandise' && isMerchandise"
|
||||||
:idReception="idReception"
|
:idReception="idReception"
|
||||||
:disabled="!auth.isAdmin"
|
:disabled="!auth.isAdmin"
|
||||||
/>
|
/>
|
||||||
@@ -141,7 +158,6 @@
|
|||||||
:idReception="idReception"
|
:idReception="idReception"
|
||||||
:disabled="!auth.isAdmin"
|
:disabled="!auth.isAdmin"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -168,6 +184,7 @@ import UpdateWeight from "~/components/reception/update-weight.vue";
|
|||||||
import UpdateMerchandise from "~/components/reception/update-merchandise.vue";
|
import UpdateMerchandise from "~/components/reception/update-merchandise.vue";
|
||||||
import UpdateBovin from "~/components/reception/update-bovin.vue";
|
import UpdateBovin from "~/components/reception/update-bovin.vue";
|
||||||
|
|
||||||
|
const activeTab = ref<'weights' | 'merchandise'>('weights')
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const receptionStore = useReceptionStore()
|
const receptionStore = useReceptionStore()
|
||||||
const form = reactive<ReceptionFormData>({
|
const form = reactive<ReceptionFormData>({
|
||||||
@@ -378,7 +395,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
||||||
watch(
|
watch(
|
||||||
() => [form.supplierId, suppliers.value],
|
() => [form.supplierId, form.addressId, suppliers.value],
|
||||||
() => {
|
() => {
|
||||||
if (!form.supplierId) {
|
if (!form.supplierId) {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
@@ -395,8 +412,12 @@ watch(
|
|||||||
(address) => String(address.id) === form.addressId
|
(address) => String(address.id) === form.addressId
|
||||||
)
|
)
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
|
if (supplierAddresses.value.length === 1) {
|
||||||
|
form.addressId = String(supplierAddresses.value[0].id)
|
||||||
|
} else {
|
||||||
form.addressId = ''
|
form.addressId = ''
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{immediate: true}
|
{immediate: true}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between h-[52px] mb-[80px]">
|
<div class="flex justify-between h-[52px] mt-6 mb-[80px]">
|
||||||
<div class="flex flex-1 mr-16">
|
<div class="flex flex-1 mr-16">
|
||||||
<UiStepper
|
<UiStepper
|
||||||
:labels="SHIPMENT_STEP_LABELS"
|
:labels="SHIPMENT_STEP_LABELS"
|
||||||
|
|||||||
@@ -19,9 +19,11 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
|||||||
new Get(
|
new Get(
|
||||||
requirements: ['id' => '\d+'],
|
requirements: ['id' => '\d+'],
|
||||||
normalizationContext: ['groups' => ['carrier:read']],
|
normalizationContext: ['groups' => ['carrier:read']],
|
||||||
|
security: "is_granted('ROLE_USER')"
|
||||||
),
|
),
|
||||||
new GetCollection(
|
new GetCollection(
|
||||||
normalizationContext: ['groups' => ['carrier:read']],
|
normalizationContext: ['groups' => ['carrier:read']],
|
||||||
|
security: "is_granted('ROLE_USER')"
|
||||||
),
|
),
|
||||||
new Post(
|
new Post(
|
||||||
normalizationContext: ['groups' => ['carrier:read']],
|
normalizationContext: ['groups' => ['carrier:read']],
|
||||||
|
|||||||
@@ -22,14 +22,11 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
|||||||
new Get(
|
new Get(
|
||||||
requirements: ['id' => '\d+'],
|
requirements: ['id' => '\d+'],
|
||||||
normalizationContext: ['groups' => ['supplier:read']],
|
normalizationContext: ['groups' => ['supplier:read']],
|
||||||
|
security: "is_granted('ROLE_USER')"
|
||||||
),
|
),
|
||||||
new GetCollection(
|
new GetCollection(
|
||||||
normalizationContext: ['groups' => ['supplier:read']],
|
normalizationContext: ['groups' => ['supplier:read']],
|
||||||
),
|
security: "is_granted('ROLE_USER')"
|
||||||
new GetCollection(
|
|
||||||
uriTemplate: '/admin/suppliers',
|
|
||||||
normalizationContext: ['groups' => ['supplier:read']],
|
|
||||||
security: "is_granted('ROLE_ADMIN')"
|
|
||||||
),
|
),
|
||||||
new Post(
|
new Post(
|
||||||
normalizationContext: ['groups' => ['supplier:read']],
|
normalizationContext: ['groups' => ['supplier:read']],
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ final class UserPasswordProcessor implements ProcessorInterface
|
|||||||
{
|
{
|
||||||
if ($data instanceof User) {
|
if ($data instanceof User) {
|
||||||
$plain = $data->getPassword();
|
$plain = $data->getPassword();
|
||||||
if ('' !== $plain) {
|
$previous = $context['previous_data'] ?? null;
|
||||||
|
if ($previous instanceof User && $plain === $previous->getPassword()) {
|
||||||
|
// Password not changed in payload: keep existing hash.
|
||||||
|
$data->setPassword($previous->getPassword());
|
||||||
|
} elseif ('' !== $plain) {
|
||||||
$data->setPassword($this->hasher->hashPassword(
|
$data->setPassword($this->hasher->hashPassword(
|
||||||
$data,
|
$data,
|
||||||
$plain
|
$plain
|
||||||
|
|||||||
Reference in New Issue
Block a user