fix : corrections diverses
This commit is contained in:
@@ -29,7 +29,7 @@
|
||||
<button
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
@click="goNext"
|
||||
>Peser
|
||||
>Valider
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
<button
|
||||
type="submit"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
|
||||
>Peser
|
||||
>Valider
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -342,7 +342,7 @@ onMounted(async () => {
|
||||
|
||||
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
||||
watch(
|
||||
() => [form.supplierId, suppliers.value],
|
||||
() => [form.supplierId, form.addressId, suppliers.value],
|
||||
() => {
|
||||
if (!form.supplierId) {
|
||||
form.addressId = ''
|
||||
@@ -359,7 +359,11 @@ watch(
|
||||
(address) => String(address.id) === form.addressId
|
||||
)
|
||||
if (!matches) {
|
||||
form.addressId = ''
|
||||
if (supplierAddresses.value.length === 1) {
|
||||
form.addressId = String(supplierAddresses.value[0].id)
|
||||
} else {
|
||||
form.addressId = ''
|
||||
}
|
||||
}
|
||||
},
|
||||
{immediate: true}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<button
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
@click="goNext"
|
||||
>Peser
|
||||
>Valider
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
v-if="displayWeight !== null && !showGenerateReceipt"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] ml-4"
|
||||
@click="saveWeight"
|
||||
>Valider la pesée</button>
|
||||
>Valider</button>
|
||||
<button
|
||||
v-if="showGenerateReceipt"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] ml-4"
|
||||
@@ -36,7 +36,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import {computed, onMounted} from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useWeighing } from '~/composables/useWeighing'
|
||||
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
|
||||
onMounted(() => {
|
||||
if (false === displayWeight.value) {
|
||||
if (displayWeight.value === null) {
|
||||
fetchWeight()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,79 +1,80 @@
|
||||
<template>
|
||||
<form @submit.prevent="validate">
|
||||
<div class="flex flex-col items-center gap-16">
|
||||
<div
|
||||
class="flex flex-col gap-16 items-center w-full">
|
||||
<UiTextInput
|
||||
id="merchandise-type"
|
||||
v-model="selectedMerchandiseTypeId"
|
||||
label="Type de marchandises"
|
||||
:value="reception.merchandiseType?.label"
|
||||
wrapper-class="w-[550px]"
|
||||
:disabled="true"
|
||||
/>
|
||||
<div class="flex flex-col items-center gap-16">
|
||||
<div
|
||||
v-if="merchandiseTypeId && isAutres"
|
||||
class="flex flex-col w-full max-w-[550px]"
|
||||
>
|
||||
class="flex flex-col gap-16 items-center w-full">
|
||||
<UiTextInput
|
||||
id="merchandise-detail"
|
||||
:disabled="!auth.isAdmin"
|
||||
v-model="merchandiseDetail"
|
||||
label="Préciser"
|
||||
placeholder="Précisions complémentaires"
|
||||
:maxlength="255"
|
||||
id="merchandise-type"
|
||||
v-model="selectedMerchandiseTypeId"
|
||||
label="Type de marchandises"
|
||||
:value="reception.merchandiseType?.label"
|
||||
wrapper-class="w-[550px]"
|
||||
:disabled="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="merchandiseTypeId && !isGranule"
|
||||
class="flex gap-4 w-[550px] justify-evenly"
|
||||
>
|
||||
<div
|
||||
v-for="building in buildings"
|
||||
:key="building.id"
|
||||
v-if="merchandiseTypeId && isAutres"
|
||||
class="flex flex-col w-full max-w-[550px]"
|
||||
>
|
||||
<UiCheckbox
|
||||
v-model="selectedBuildingIds"
|
||||
:value="String(building.id)"
|
||||
:label="building.label"
|
||||
<UiTextInput
|
||||
id="merchandise-detail"
|
||||
:disabled="!auth.isAdmin"
|
||||
label-class="text-xl"
|
||||
v-model="merchandiseDetail"
|
||||
label="Préciser"
|
||||
placeholder="Précisions complémentaires"
|
||||
:maxlength="255"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="merchandiseTypeId && isGranule"
|
||||
class="flex flex-col gap-10 w-full max-w-[1100px]"
|
||||
>
|
||||
<div class="grid grid-cols-1 gap-10 md:grid-cols-4">
|
||||
<div v-for="type in pelletTypes" :key="type.id" class="flex flex-col gap-4">
|
||||
<p class="font-bold uppercase">{{ type.label }}</p>
|
||||
<div
|
||||
v-for="building in buildings"
|
||||
:key="building.id"
|
||||
class="flex items-center gap-2 text-lg"
|
||||
>
|
||||
<UiCheckbox
|
||||
v-model="selectedPelletBuildingIds[String(type.id)]"
|
||||
:value="String(building.id)"
|
||||
:label="building.label"
|
||||
:disabled="!auth.isAdmin"
|
||||
label-class="text-lg"
|
||||
/>
|
||||
<div
|
||||
v-if="merchandiseTypeId && !isGranule"
|
||||
class="flex gap-4 w-[550px] justify-evenly"
|
||||
>
|
||||
<div
|
||||
v-for="building in buildings"
|
||||
:key="building.id"
|
||||
>
|
||||
<UiCheckbox
|
||||
v-model="selectedBuildingIds"
|
||||
:value="String(building.id)"
|
||||
:label="building.label"
|
||||
:disabled="!auth.isAdmin"
|
||||
label-class="text-xl"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="merchandiseTypeId && isGranule"
|
||||
class="flex flex-col gap-10 w-full max-w-[1100px]"
|
||||
>
|
||||
<div class="grid grid-cols-1 gap-10 md:grid-cols-4">
|
||||
<div v-for="type in pelletTypes" :key="type.id" class="flex flex-col gap-4">
|
||||
<p class="font-bold uppercase">{{ type.label }}</p>
|
||||
<div
|
||||
v-for="building in buildings"
|
||||
:key="building.id"
|
||||
class="flex items-center gap-2 text-lg"
|
||||
>
|
||||
<UiCheckbox
|
||||
v-model="selectedPelletBuildingIds[String(type.id)]"
|
||||
:value="String(building.id)"
|
||||
:label="building.label"
|
||||
:disabled="!auth.isAdmin"
|
||||
label-class="text-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
v-if="auth.isAdmin"
|
||||
type="submit"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
:disabled="!auth.isAdmin"
|
||||
>Valider
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
:disabled="!auth.isAdmin"
|
||||
>Valider
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,27 +1,42 @@
|
||||
<template>
|
||||
<form @submit.prevent="validate">
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-40 gap-y-8 mb-16">
|
||||
<div class="grid grid-cols-2 gap-x-40 gap-y-8 mb-8">
|
||||
<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
|
||||
label="Pesée à vide"
|
||||
labelClass="font-bold uppercase text-xl"
|
||||
v-model="form.weights[0].weight"
|
||||
wrapper-class="col-start-1 row-start-1"
|
||||
:disabled="!auth.isAdmin"
|
||||
:min="0"
|
||||
/>
|
||||
|
||||
<UiNumberInput
|
||||
label="Pesée à plein"
|
||||
labelClass="font-bold uppercase text-xl"
|
||||
v-model="form.weights[1].weight"
|
||||
wrapper-class="col-start-2 row-start-1"
|
||||
:disabled="!auth.isAdmin"
|
||||
:min="0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<button
|
||||
v-if="auth.isAdmin"
|
||||
type="submit"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
:disabled="!auth.isAdmin"
|
||||
|
||||
>
|
||||
Valider
|
||||
</button>
|
||||
@@ -32,7 +47,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {ReceptionFormWeight} from '~/services/dto/reception-data'
|
||||
import { getReception } from '~/services/reception'
|
||||
import {getReception} from '~/services/reception'
|
||||
import {updateWeight} from "~/services/weight";
|
||||
import {useAuthStore} from "~/stores/auth";
|
||||
|
||||
@@ -45,8 +60,8 @@ const auth = useAuthStore()
|
||||
|
||||
const form = reactive({
|
||||
weights: [
|
||||
{ id: 0, type: 'tare' as const, weight: 0 },
|
||||
{ id: 0, type: 'gross' as const, weight: 0 }
|
||||
{id: 0, type: 'tare' as const, weight: 0, dsd: null, weighedAt: null},
|
||||
{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 gross = reception.weights.find(weight => weight.type === 'gross')
|
||||
|
||||
if (tare) form.weights[0] = { ...tare }
|
||||
if (gross) form.weights[1] = { ...gross }
|
||||
if (tare) form.weights[0] = {...form.weights[0], ...tare}
|
||||
if (gross) form.weights[1] = {...form.weights[1], ...gross}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -64,11 +79,24 @@ onMounted(async () => {
|
||||
})
|
||||
|
||||
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) {
|
||||
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>
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
/>
|
||||
<!-- Type d'expédition -->
|
||||
<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
|
||||
</label>
|
||||
<div class="grid grid-cols-2 gap-x-8">
|
||||
<div
|
||||
v-for="type in bovineShipment"
|
||||
:key="type.id"
|
||||
class="mt-8 flex flex-row gap-6"
|
||||
class="mt-2 flex flex-row gap-6"
|
||||
>
|
||||
<UiNumberInput
|
||||
:label="type.label"
|
||||
@@ -344,7 +344,7 @@ watch(
|
||||
)
|
||||
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
||||
watch(
|
||||
() => [form.customerId, customers.value],
|
||||
() => [form.customerId, form.addressId, customers.value],
|
||||
() => {
|
||||
if (!form.customerId) {
|
||||
form.addressId = ''
|
||||
@@ -361,7 +361,11 @@ watch(
|
||||
(address) => String(address.id) === form.addressId
|
||||
)
|
||||
if (!matches) {
|
||||
form.addressId = ''
|
||||
if (customerAddresses.value.length === 1) {
|
||||
form.addressId = String(customerAddresses.value[0].id)
|
||||
} else {
|
||||
form.addressId = ''
|
||||
}
|
||||
}
|
||||
},
|
||||
{immediate: true}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<label
|
||||
v-if="label"
|
||||
:for="id"
|
||||
class="text-xl text-bold flex items-center"
|
||||
class="text-xl flex items-center"
|
||||
:class="labelClass"
|
||||
>
|
||||
<span
|
||||
@@ -25,7 +25,7 @@
|
||||
:step="step"
|
||||
:disabled="disabled"
|
||||
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="[
|
||||
isEmpty ? 'text-neutral-400' : 'text-black',
|
||||
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">
|
||||
<div class="flex flex-col gap-4 p-4 font-bold text-xl">
|
||||
<!-- Liste des liens à ajouter ci-dessous -->
|
||||
<NuxtLink to="/admin/dashboard">
|
||||
Tableau de bord
|
||||
<NuxtLink
|
||||
to="/admin/dashboard"
|
||||
custom v-slot="{ href, navigate, isExactActive }">
|
||||
<a :href="href"
|
||||
@click="navigate"
|
||||
:class="isExactActive ? 'opacity-100' : 'opacity-50'">
|
||||
Tableau de bord
|
||||
</a>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/supplier/supplier-list">
|
||||
Fournisseur
|
||||
<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
|
||||
</a>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/carrier/carrier-list">
|
||||
Transporteur
|
||||
<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
|
||||
</a>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/user/list">
|
||||
Utilisateurs
|
||||
<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
|
||||
</a>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/customer/customer-list">
|
||||
Client
|
||||
@@ -42,19 +66,22 @@
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<p class="font-bold text-white text-left">v{{ version }}</p>
|
||||
|
||||
<button
|
||||
@click="handleLogout"
|
||||
class="w-full bg-red-600 hover:bg-red-700 py-2 rounded font-bold"
|
||||
>
|
||||
Déconnexion
|
||||
</button>
|
||||
<p class="font-bold text-white text-center pt-2">
|
||||
v{{ version }}
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="min-h-0 overflow-auto px-12 py-12 ">
|
||||
<div class="w-full ">
|
||||
<slot />
|
||||
<slot/>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
@@ -66,7 +93,9 @@
|
||||
import {useAuthStore} from '~/stores/auth'
|
||||
|
||||
const auth = useAuthStore()
|
||||
const { version } = useAppVersion()
|
||||
const {version} = useAppVersion()
|
||||
|
||||
const route = useRoute()
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await auth.logout()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="min-h-screen bg-white text-neutral-900">
|
||||
<header class="w-full border-b border-neutral-200 bg-primary-500">
|
||||
<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">
|
||||
<div class="flex w-full items-center justify-center px-6 py-4">
|
||||
<button
|
||||
type="button"
|
||||
@@ -21,12 +21,13 @@
|
||||
</a>
|
||||
</NuxtLink>
|
||||
<NuxtLink
|
||||
to="/admin/dashboard" custom v-slot="{ href, navigate, isActive }"
|
||||
to="/admin/dashboard" custom v-slot="{ href, navigate, isExactActive }"
|
||||
v-if="auth.isAdmin"
|
||||
>
|
||||
<a
|
||||
:href="href"
|
||||
@click="navigate"
|
||||
:class="isExactActive ? 'opacity-100' : 'opacity-50'"
|
||||
>
|
||||
Admin
|
||||
</a>
|
||||
@@ -100,7 +101,7 @@
|
||||
</aside>
|
||||
</transition>
|
||||
</header>
|
||||
<main class="mx-auto w-full max-w-[1280px] pb-0">
|
||||
<main class="mx-auto w-full max-w-[1280px]">
|
||||
<slot/>
|
||||
</main>
|
||||
<footer class="w-full mt-8 bg-primary-500 p-6">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<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">
|
||||
{{ supplierId ? "Modifications du fournisseur" : "Ajout d'un fournisseur" }}
|
||||
</h1>
|
||||
@@ -14,13 +14,13 @@
|
||||
</button>
|
||||
</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-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"/>
|
||||
</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">
|
||||
<h2 class="text-3xl font-bold uppercase">Adresses fournisseur</h2>
|
||||
<button
|
||||
@@ -179,14 +179,17 @@ async function validate() {
|
||||
email,
|
||||
phone,
|
||||
}
|
||||
let targetId: number | null = null
|
||||
|
||||
if (supplierId.value !== null) {
|
||||
await updateSupplier(supplierId.value, supplierPayload)
|
||||
targetId = supplierId.value
|
||||
} 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 {
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<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
|
||||
to="/admin/supplier"
|
||||
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 {ROLE} from '~/utils/constants'
|
||||
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 router = useRouter()
|
||||
@@ -105,10 +105,12 @@ async function validate() {
|
||||
const normalizedRole = form.role.trim()
|
||||
const normalizedPassword = form.password.trim()
|
||||
|
||||
const basePayload = {
|
||||
const basePayload: UserPayload = {
|
||||
username: normalizedUsername,
|
||||
roles: normalizedRole ? [normalizedRole] : undefined,
|
||||
password: normalizedPassword || undefined
|
||||
}
|
||||
if (normalizedPassword) {
|
||||
basePayload.password = normalizedPassword
|
||||
}
|
||||
|
||||
if (userId.value) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<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">
|
||||
<UiStepper
|
||||
:labels="RECEPTION_STEP_LABELS"
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
<template>
|
||||
|
||||
<form @submit.prevent="validate">
|
||||
<div class="flex items-center justify-between mt-8 mb-8 ">
|
||||
<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 class="flex items-center justify-between mt-12 mb-8 ">
|
||||
<h1 class="font-bold text-5xl uppercase">Réception {{ receptionLoad?.identificationNumber }}</h1>
|
||||
</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 -->
|
||||
<UiSelect
|
||||
id="reception-user"
|
||||
@@ -120,28 +114,50 @@
|
||||
wrapper-class="col-start-2 row-start-4"
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-start gap-y-8 gap-x-40 mb-16">
|
||||
<h1 class="font-bold text-5xl uppercase col-start-1 row-start-1" @click="isBtWeight = true" >pesées</h1>
|
||||
<h1 class="font-bold text-5xl uppercase col-start-2 row-start-1" @click="isBtWeight = false">{{isMerchandise ? "Marchandises" : "Bovins"}}</h1>
|
||||
<div class="flex justify-center mb-2">
|
||||
<button
|
||||
v-if="auth.isAdmin"
|
||||
type="submit"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] mb-16"
|
||||
|
||||
>
|
||||
Enregistrer
|
||||
</button>
|
||||
</div>
|
||||
<update-weight
|
||||
v-if="isBtWeight"
|
||||
:idReception="idReception"
|
||||
:disabled="!auth.isAdmin"
|
||||
/>
|
||||
<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-merchandise
|
||||
v-else-if="isMerchandise"
|
||||
:idReception="idReception"
|
||||
:disabled="!auth.isAdmin"
|
||||
/>
|
||||
<update-weight
|
||||
v-if="activeTab === 'weights'"
|
||||
:idReception="idReception"
|
||||
:disabled="!auth.isAdmin"
|
||||
/>
|
||||
|
||||
<update-bovin
|
||||
v-else
|
||||
:idReception="idReception"
|
||||
:disabled="!auth.isAdmin"
|
||||
/>
|
||||
<update-merchandise
|
||||
v-else-if="activeTab === 'merchandise' && isMerchandise"
|
||||
:idReception="idReception"
|
||||
:disabled="!auth.isAdmin"
|
||||
/>
|
||||
|
||||
<update-bovin
|
||||
v-else
|
||||
:idReception="idReception"
|
||||
:disabled="!auth.isAdmin"
|
||||
/>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
@@ -168,6 +184,7 @@ import UpdateWeight from "~/components/reception/update-weight.vue";
|
||||
import UpdateMerchandise from "~/components/reception/update-merchandise.vue";
|
||||
import UpdateBovin from "~/components/reception/update-bovin.vue";
|
||||
|
||||
const activeTab = ref<'weights' | 'merchandise'>('weights')
|
||||
const router = useRouter()
|
||||
const receptionStore = useReceptionStore()
|
||||
const form = reactive<ReceptionFormData>({
|
||||
@@ -249,7 +266,7 @@ const clearReceptionBovines = async (receptionIri: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const hydrateFromUser = (reception: ReceptionData | null)=> {
|
||||
const hydrateFromUser = (reception: ReceptionData | null) => {
|
||||
if (!reception) {
|
||||
return
|
||||
}
|
||||
@@ -378,7 +395,7 @@ onMounted(async () => {
|
||||
|
||||
// Ajuste driver/vehicle quand le transporteur change (logique LIOT)
|
||||
watch(
|
||||
() => [form.supplierId, suppliers.value],
|
||||
() => [form.supplierId, form.addressId, suppliers.value],
|
||||
() => {
|
||||
if (!form.supplierId) {
|
||||
form.addressId = ''
|
||||
@@ -395,7 +412,11 @@ watch(
|
||||
(address) => String(address.id) === form.addressId
|
||||
)
|
||||
if (!matches) {
|
||||
form.addressId = ''
|
||||
if (supplierAddresses.value.length === 1) {
|
||||
form.addressId = String(supplierAddresses.value[0].id)
|
||||
} else {
|
||||
form.addressId = ''
|
||||
}
|
||||
}
|
||||
},
|
||||
{immediate: true}
|
||||
@@ -532,7 +553,7 @@ async function validate() {
|
||||
}
|
||||
|
||||
if (idReception) {
|
||||
const updated = await receptionStore.updateReception(idReception,{
|
||||
const updated = await receptionStore.updateReception(idReception, {
|
||||
...payload
|
||||
})
|
||||
if (updated) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<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">
|
||||
<UiStepper
|
||||
:labels="SHIPMENT_STEP_LABELS"
|
||||
|
||||
@@ -19,9 +19,11 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
||||
new Get(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['carrier:read']],
|
||||
security: "is_granted('ROLE_USER')"
|
||||
),
|
||||
new GetCollection(
|
||||
normalizationContext: ['groups' => ['carrier:read']],
|
||||
security: "is_granted('ROLE_USER')"
|
||||
),
|
||||
new Post(
|
||||
normalizationContext: ['groups' => ['carrier:read']],
|
||||
|
||||
@@ -22,14 +22,11 @@ use Symfony\Component\Serializer\Attribute\Groups;
|
||||
new Get(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['supplier:read']],
|
||||
security: "is_granted('ROLE_USER')"
|
||||
),
|
||||
new GetCollection(
|
||||
normalizationContext: ['groups' => ['supplier:read']],
|
||||
),
|
||||
new GetCollection(
|
||||
uriTemplate: '/admin/suppliers',
|
||||
normalizationContext: ['groups' => ['supplier:read']],
|
||||
security: "is_granted('ROLE_ADMIN')"
|
||||
security: "is_granted('ROLE_USER')"
|
||||
),
|
||||
new Post(
|
||||
normalizationContext: ['groups' => ['supplier:read']],
|
||||
|
||||
@@ -21,8 +21,12 @@ final class UserPasswordProcessor implements ProcessorInterface
|
||||
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed
|
||||
{
|
||||
if ($data instanceof User) {
|
||||
$plain = $data->getPassword();
|
||||
if ('' !== $plain) {
|
||||
$plain = $data->getPassword();
|
||||
$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,
|
||||
$plain
|
||||
|
||||
Reference in New Issue
Block a user