[#325] Corrections diverses (!26)
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled

| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|         #325         |       Corrections diverses          |

## Description de la PR

## Modification du .env

## Check list

- [x] Pas de régression
- [ ] TU/TI/TF rédigée
- [x] TU/TI/TF OK
- [x] CHANGELOG modifié

Reviewed-on: #26
Reviewed-by: Autin <tristan@yuno.malio.fr>
Co-authored-by: kevin <kevin@yuno.malio.fr>
Co-committed-by: kevin <kevin@yuno.malio.fr>
This commit was merged in pull request #26.
This commit is contained in:
2026-02-13 08:10:33 +00:00
committed by Autin
parent 22b959de85
commit 7f3d9ef9c6
23 changed files with 384 additions and 274 deletions

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourcePerFileMappings">
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/f407a514-c6b4-4b26-9555-445a85892502/console.sql" value="f407a514-c6b4-4b26-9555-445a85892502" />
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/f407a514-c6b4-4b26-9555-445a85892502/console_1.sql" value="f407a514-c6b4-4b26-9555-445a85892502" />
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/f407a514-c6b4-4b26-9555-445a85892502/console_2.sql" value="f407a514-c6b4-4b26-9555-445a85892502" />
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/f407a514-c6b4-4b26-9555-445a85892502/console_3.sql" value="f407a514-c6b4-4b26-9555-445a85892502" />
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/f407a514-c6b4-4b26-9555-445a85892502/console_4.sql" value="f407a514-c6b4-4b26-9555-445a85892502" />
</component>
</project>

216
.idea/workspace.xml generated
View File

@@ -4,28 +4,10 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)"> <list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="fix : corrections diverses">
<change afterPath="$PROJECT_DIR$/frontend/components/shipment/shipment-form.vue" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/data_source_mapping.xml" beforeDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/pages/shipment/[[id]].vue" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/bovin-shipment.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/customer.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/dto/bovin-shipment-data.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/dto/customer-data.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/dto/shipment-data.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/dto/shipment-type-data.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/shipment-type.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/services/shipment.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/frontend/stores/shipment.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/reference.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/reference.php" afterDir="false" /> <change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/components/ui/UiNumberInput.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/ui/UiNumberInput.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/constants/steps.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/constants/steps.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/i18n/locales/fr.json" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/i18n/locales/fr.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/pages/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/services/reception.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/services/reception.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Entity/Address.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/Address.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Entity/BovinShipment.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/BovinShipment.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Entity/Shipment.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/Shipment.php" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -50,17 +32,21 @@
<list> <list>
<option value="Vue Composition API Component" /> <option value="Vue Composition API Component" />
<option value="TypeScript File" /> <option value="TypeScript File" />
<option value="PHP File" />
</list> </list>
</option> </option>
</component> </component>
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY"> <option name="RECENT_BRANCH_BY_REPOSITORY">
<map> <map>
<entry key="$PROJECT_DIR$" value="fix/makefile" /> <entry key="$PROJECT_DIR$" value="feat/276-lister-expeditions-terminees" />
</map> </map>
</option> </option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component> </component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/frontend/pages/admin/supplier/supplier-list.vue" root0="FORCE_HIGHLIGHTING" />
</component>
<component name="McpProjectServerCommands"> <component name="McpProjectServerCommands">
<commands /> <commands />
<urls /> <urls />
@@ -237,37 +223,42 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
"RunOnceActivity.MCP Project settings loaded": "true", &quot;RunOnceActivity.MCP Project settings loaded&quot;: &quot;true&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true", &quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
"RunOnceActivity.git.unshallow": "true", &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
"RunOnceActivity.typescript.service.memoryLimit.init": "true", &quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
"git-widget-placeholder": "feat/271-expedition-etape-1", &quot;git-widget-placeholder&quot;: &quot;fix/325-corrections-diverses&quot;,
"last_opened_file_path": "/home/sroy/Documents/test/Ferme", &quot;last_opened_file_path&quot;: &quot;//wsl.localhost/Ubuntu-24.04/home/kevin/Stage/Ferme/frontend/pages/shipment&quot;,
"node.js.detected.package.eslint": "true", &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
"node.js.detected.package.tslint": "true", &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
"node.js.selected.package.eslint": "(autodetect)", &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
"node.js.selected.package.tslint": "(autodetect)", &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
"nodejs_package_manager_path": "npm", &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
"settings.editor.selected.configurable": "configurable.tailwindcss", &quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
"ts.external.directory.path": "/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external", &quot;ts.external.directory.path&quot;: &quot;/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external&quot;,
"vue.rearranger.settings.migration": "true" &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}, },
"keyToStringList": { &quot;keyToStringList&quot;: {
"DatabaseDriversLRU": [ &quot;DatabaseDriversLRU&quot;: [
"postgresql" &quot;postgresql&quot;
], ],
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [ &quot;com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File&quot;: [
"TEXT" &quot;TEXT&quot;
], ],
"vue.recent.templates": [ &quot;vue.recent.templates&quot;: [
"Vue Composition API Component" &quot;Vue Composition API Component&quot;
] ]
} }
}]]></component> }</component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="\\wsl.localhost\Ubuntu-24.04\home\kevin\Stage\Ferme\frontend\pages\shipment" />
<recent name="\\wsl.localhost\Ubuntu-24.04\home\kevin\Stage\Ferme\frontend\composables" />
<recent name="\\wsl.localhost\Ubuntu-24.04\home\kevin\Stage\Ferme\frontend\components\shipment" />
</key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="\\wsl.localhost\Ubuntu-24.04\home\m-tristan\workspace\Ferme" /> <recent name="\\wsl.localhost\Ubuntu-24.04\home\m-tristan\workspace\Ferme" />
<recent name="\\wsl.localhost\Ubuntu-24.04\home\tristan\workspace\ferme\templates" /> <recent name="\\wsl.localhost\Ubuntu-24.04\home\tristan\workspace\ferme\templates" />
@@ -313,54 +304,10 @@
<workItem from="1770195718952" duration="215000" /> <workItem from="1770195718952" duration="215000" />
<workItem from="1770195959162" duration="18915000" /> <workItem from="1770195959162" duration="18915000" />
<workItem from="1770274844804" duration="3940000" /> <workItem from="1770274844804" duration="3940000" />
</task> <workItem from="1770798536017" duration="20774000" />
<task id="LOCAL-00001" summary="feat : Ajout de pinia, création de la table weight et reception mise en place du système de step pour les receptions (WIP)"> <workItem from="1770879701502" duration="25805000" />
<option name="closed" value="true" /> <workItem from="1770966186589" duration="914000" />
<created>1768237763998</created> <workItem from="1770967274060" duration="2388000" />
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1768237763998</updated>
</task>
<task id="LOCAL-00002" summary="feat : Ajout de zod, création d'un composant de chargement loading-dots.vue et finalisation du flow d'une reception">
<option name="closed" value="true" />
<created>1768316052474</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1768316052474</updated>
</task>
<task id="LOCAL-00003" summary="feat : Ajout d'un composable pour la pesée qui sera réutilisable pour l'expédition, ajout de contrainte sur les entity de reception et weight pour plus de robustesse et correction de la class active des liens dans la nav">
<option name="closed" value="true" />
<created>1768316835575</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1768316835575</updated>
</task>
<task id="LOCAL-00004" summary="feat : update du fichier AGENTS.md">
<option name="closed" value="true" />
<created>1768316965511</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1768316965511</updated>
</task>
<task id="LOCAL-00005" summary="feat : update du fichier README.md et CHANGELOG.md">
<option name="closed" value="true" />
<created>1768317786187</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1768317786187</updated>
</task>
<task id="LOCAL-00006" summary="fix : correction du useApi pour qu'il n'y ait plus de retry lors d'une erreur 500 par exemple">
<option name="closed" value="true" />
<created>1768318875533</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1768318875533</updated>
</task> </task>
<task id="LOCAL-00007" summary="test : ajout de TU sur les services et providers"> <task id="LOCAL-00007" summary="test : ajout de TU sur les services et providers">
<option name="closed" value="true" /> <option name="closed" value="true" />
@@ -706,7 +653,55 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1770217875423</updated> <updated>1770217875423</updated>
</task> </task>
<option name="localTasksCounter" value="50" /> <task id="LOCAL-00050" summary="feat : creer une nouvelle expedtion (WIP)">
<option name="closed" value="true" />
<created>1770736570645</created>
<option name="number" value="00050" />
<option name="presentableId" value="LOCAL-00050" />
<option name="project" value="LOCAL" />
<updated>1770736570645</updated>
</task>
<task id="LOCAL-00051" summary="feat : ajout d'une page de creation d'une expedition">
<option name="closed" value="true" />
<created>1770880791564</created>
<option name="number" value="00051" />
<option name="presentableId" value="LOCAL-00051" />
<option name="project" value="LOCAL" />
<updated>1770880791565</updated>
</task>
<task id="LOCAL-00052" summary="feat : changelog">
<option name="closed" value="true" />
<created>1770881437439</created>
<option name="number" value="00052" />
<option name="presentableId" value="LOCAL-00052" />
<option name="project" value="LOCAL" />
<updated>1770881437439</updated>
</task>
<task id="LOCAL-00053" summary="feat : lister les expeditions terminees">
<option name="closed" value="true" />
<created>1770883114609</created>
<option name="number" value="00053" />
<option name="presentableId" value="LOCAL-00053" />
<option name="project" value="LOCAL" />
<updated>1770883114609</updated>
</task>
<task id="LOCAL-00054" summary="feat : lister les expeditions terminees">
<option name="closed" value="true" />
<created>1770884154297</created>
<option name="number" value="00054" />
<option name="presentableId" value="LOCAL-00054" />
<option name="project" value="LOCAL" />
<updated>1770884154297</updated>
</task>
<task id="LOCAL-00055" summary="fix : corrections diverses">
<option name="closed" value="true" />
<created>1770969471135</created>
<option name="number" value="00055" />
<option name="presentableId" value="LOCAL-00055" />
<option name="project" value="LOCAL" />
<updated>1770969471135</updated>
</task>
<option name="localTasksCounter" value="56" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@@ -756,12 +751,6 @@
</option> </option>
</component> </component>
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<MESSAGE value="fix : correction du path URI pour la création d'un poids dans une réception" />
<MESSAGE value="feat : Ajout du bundle Monolog pour la gestion des logs" />
<MESSAGE value="fix : affiche plus détail dans les logs en recette/prod" />
<MESSAGE value="fix : modification du script de déploiement pour corriger le problème d'écriture des logs de prod" />
<MESSAGE value="fix : doc de déploiement" />
<MESSAGE value="fix : doc et script de déploiement" />
<MESSAGE value="fix : gitea workflow" /> <MESSAGE value="fix : gitea workflow" />
<MESSAGE value="fix : script de déploiement" /> <MESSAGE value="fix : script de déploiement" />
<MESSAGE value="feat : ajout plus d'information sur la liste des réceptions côté front sur la page d'accueil" /> <MESSAGE value="feat : ajout plus d'information sur la liste des réceptions côté front sur la page d'accueil" />
@@ -781,7 +770,13 @@
<MESSAGE value="feat : ajout de colonne pour les Supplier, Address. Modification du numéro de réception et ajout de fixtures" /> <MESSAGE value="feat : ajout de colonne pour les Supplier, Address. Modification du numéro de réception et ajout de fixtures" />
<MESSAGE value="feat : mise à jour du bon de réception" /> <MESSAGE value="feat : mise à jour du bon de réception" />
<MESSAGE value="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)" /> <MESSAGE value="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)" />
<option name="LAST_COMMIT_MESSAGE" value="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)" /> <MESSAGE value="feat : creer une nouvelle expedtion (WIP)" />
<MESSAGE value="feat : ajout d'une page de creation d'une expedition" />
<MESSAGE value="feat : changelog" />
<MESSAGE value="feat : lister les expeditions terminees" />
<MESSAGE value="fix: corrections diverses" />
<MESSAGE value="fix : corrections diverses" />
<option name="LAST_COMMIT_MESSAGE" value="fix : corrections diverses" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager> <breakpoint-manager>
@@ -791,10 +786,19 @@
<line>6</line> <line>6</line>
<option name="timeStamp" value="3" /> <option name="timeStamp" value="3" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="php">
<url>file://$PROJECT_DIR$/src/Entity/Shipment.php</url>
<line>6</line>
<option name="timeStamp" value="45" />
</line-breakpoint>
<line-breakpoint enabled="true" type="javascript"> <line-breakpoint enabled="true" type="javascript">
<url>file://$PROJECT_DIR$/frontend/services/shipment.ts</url> <url>file://$PROJECT_DIR$/frontend/services/dto/shipment-data.ts</url>
<properties lambdaOrdinal="-1" /> <option name="timeStamp" value="43" />
<option name="timeStamp" value="37" /> </line-breakpoint>
<line-breakpoint enabled="true" type="javascript">
<url>file://$PROJECT_DIR$/frontend/layouts/default.vue</url>
<line>72</line>
<option name="timeStamp" value="48" />
</line-breakpoint> </line-breakpoint>
</breakpoints> </breakpoints>
</breakpoint-manager> </breakpoint-manager>

View File

@@ -45,6 +45,7 @@ Ajouter dans le fichier .env du frontend
* [#276] Lister les expéditions terminées * [#276] Lister les expéditions terminées
* [#324] Creation page admin listing clients * [#324] Creation page admin listing clients
* [#326] Admin modification creation client * [#326] Admin modification creation client
* [#325] Correction diverses
### Changed ### Changed

View File

@@ -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>

View File

@@ -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,7 +359,11 @@ watch(
(address) => String(address.id) === form.addressId (address) => String(address.id) === form.addressId
) )
if (!matches) { if (!matches) {
form.addressId = '' if (supplierAddresses.value.length === 1) {
form.addressId = String(supplierAddresses.value[0].id)
} else {
form.addressId = ''
}
} }
}, },
{immediate: true} {immediate: true}

View File

@@ -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>

View File

@@ -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()
} }
}) })

View File

@@ -1,79 +1,80 @@
<template> <template>
<form @submit.prevent="validate"> <form @submit.prevent="validate">
<div class="flex flex-col items-center gap-16"> <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 <div
v-if="merchandiseTypeId && isAutres" class="flex flex-col gap-16 items-center w-full">
class="flex flex-col w-full max-w-[550px]"
>
<UiTextInput <UiTextInput
id="merchandise-detail" id="merchandise-type"
:disabled="!auth.isAdmin" v-model="selectedMerchandiseTypeId"
v-model="merchandiseDetail" label="Type de marchandises"
label="Préciser" :value="reception.merchandiseType?.label"
placeholder="Précisions complémentaires" wrapper-class="w-[550px]"
:maxlength="255" :disabled="true"
/> />
</div>
<div
v-if="merchandiseTypeId && !isGranule"
class="flex gap-4 w-[550px] justify-evenly"
>
<div <div
v-for="building in buildings" v-if="merchandiseTypeId && isAutres"
:key="building.id" class="flex flex-col w-full max-w-[550px]"
> >
<UiCheckbox <UiTextInput
v-model="selectedBuildingIds" id="merchandise-detail"
:value="String(building.id)"
:label="building.label"
:disabled="!auth.isAdmin" :disabled="!auth.isAdmin"
label-class="text-xl" v-model="merchandiseDetail"
label="Préciser"
placeholder="Précisions complémentaires"
:maxlength="255"
/> />
</div> </div>
</div>
<div <div
v-if="merchandiseTypeId && isGranule" v-if="merchandiseTypeId && !isGranule"
class="flex flex-col gap-10 w-full max-w-[1100px]" class="flex gap-4 w-[550px] justify-evenly"
> >
<div class="grid grid-cols-1 gap-10 md:grid-cols-4"> <div
<div v-for="type in pelletTypes" :key="type.id" class="flex flex-col gap-4"> v-for="building in buildings"
<p class="font-bold uppercase">{{ type.label }}</p> :key="building.id"
<div >
v-for="building in buildings" <UiCheckbox
:key="building.id" v-model="selectedBuildingIds"
class="flex items-center gap-2 text-lg" :value="String(building.id)"
> :label="building.label"
<UiCheckbox :disabled="!auth.isAdmin"
v-model="selectedPelletBuildingIds[String(type.id)]" label-class="text-xl"
:value="String(building.id)" />
:label="building.label" </div>
:disabled="!auth.isAdmin" </div>
label-class="text-lg"
/> <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>
</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> </div>
<button
type="submit"
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
:disabled="!auth.isAdmin"
>Valider
</button>
</div>
</form> </form>
</template> </template>

View File

@@ -1,27 +1,36 @@
<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
<UiNumberInput label="Dsd"
label="Pesée à vide" class="col-start-2"
v-model="form.weights[0].weight" v-model="sharedWeightMeta.dsd"
:disabled="!auth.isAdmin" :disabled="!auth.isAdmin"
:min="0"
/> />
<UiDateInput
<UiNumberInput label="Date pesée"
label="Pesée à plein" v-model="sharedWeightMeta.weighedAt"
v-model="form.weights[1].weight" :disabled="!auth.isAdmin"
/>
</div>
<div class="grid grid-cols-2 gap-x-40 mb-16">
<UiNumberInput
v-for="weight in form.weights"
:key="weight.type"
:label="getWeightLabel(weight.type)"
labelClass="font-bold uppercase text-xl"
v-model="weight.weight"
:wrapper-class="weight.type === 'tare' ? 'col-start-1 row-start-1' : '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>
@@ -32,7 +41,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type {ReceptionFormWeight} from '~/services/dto/reception-data' import type {ReceptionFormWeight} from '~/services/dto/reception-data'
import { getReception } from '~/services/reception' import {getReception} from '~/services/reception'
import {updateWeight} from "~/services/weight"; import {updateWeight} from "~/services/weight";
import {useAuthStore} from "~/stores/auth"; import {useAuthStore} from "~/stores/auth";
@@ -45,17 +54,42 @@ 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}
] ]
}) })
// 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 getWeightLabel = (type: 'tare' | 'gross'): string => {
return type === 'tare' ? 'Pesée à vide' : 'Pesée à plein'
}
const hydrateFromReception = (reception: ReceptionFormWeight) => { const hydrateFromReception = (reception: ReceptionFormWeight) => {
const tare = reception.weights.find(weight => weight.type === 'tare') // On hydrate chaque ligne par son type (tare/gross), sans dépendre d'un index.
const gross = reception.weights.find(weight => weight.type === 'gross') for (const receptionWeight of reception.weights) {
const formWeight = form.weights.find(weight => weight.type === receptionWeight.type)
if (formWeight) {
Object.assign(formWeight, receptionWeight)
}
}
if (tare) form.weights[0] = { ...tare } // On récupère une valeur existante pour préremplir les champs partagés.
if (gross) form.weights[1] = { ...gross } 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
}
} }
onMounted(async () => { onMounted(async () => {
@@ -64,11 +98,23 @@ onMounted(async () => {
}) })
async function validate() { async function validate() {
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
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>

View File

@@ -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,7 +361,11 @@ watch(
(address) => String(address.id) === form.addressId (address) => String(address.id) === form.addressId
) )
if (!matches) { if (!matches) {
form.addressId = '' if (customerAddresses.value.length === 1) {
form.addressId = String(customerAddresses.value[0].id)
} else {
form.addressId = ''
}
} }
}, },
{immediate: true} {immediate: true}

View File

@@ -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',

View File

@@ -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
Tableau de bord 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>
<NuxtLink to="/admin/supplier/supplier-list"> <NuxtLink
Fournisseur 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>
<NuxtLink to="/admin/carrier/carrier-list"> <NuxtLink
Transporteur 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>
<NuxtLink to="/admin/user/list"> <NuxtLink to="/admin/user/list" custom v-slot="{ href, navigate }">
Utilisateurs <a
:href="href"
@click="navigate"
:class="route.path.startsWith('/admin/user') ? 'opacity-100' : 'opacity-50'"
>
Utilisateurs
</a>
</NuxtLink> </NuxtLink>
<NuxtLink to="/admin/customer/customer-list"> <NuxtLink to="/admin/customer/customer-list">
Client Client
@@ -42,19 +66,22 @@
</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>
<main class="min-h-0 overflow-auto px-12 py-12 "> <main class="min-h-0 overflow-auto px-12 py-12 ">
<div class="w-full "> <div class="w-full ">
<slot /> <slot/>
</div> </div>
</main> </main>
</div> </div>
@@ -66,7 +93,9 @@
import {useAuthStore} from '~/stores/auth' 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()

View File

@@ -1,6 +1,6 @@
<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
type="button" type="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">

View File

@@ -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
} }

View File

@@ -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]"

View File

@@ -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) {

View File

@@ -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"

View File

@@ -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,28 +114,50 @@
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>
<update-weight <div class="flex justify-evenly gap-y-8 gap-x-40 mb-8 border-b border-slate-400">
v-if="isBtWeight" <h1
:idReception="idReception" class="font-bold text-3xl uppercase col-start-1 row-start-1 cursor-pointer"
:disabled="!auth.isAdmin" :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 <update-weight
v-else-if="isMerchandise" v-if="activeTab === 'weights'"
:idReception="idReception" :idReception="idReception"
:disabled="!auth.isAdmin" :disabled="!auth.isAdmin"
/> />
<update-bovin <update-merchandise
v-else v-else-if="activeTab === 'merchandise' && isMerchandise"
:idReception="idReception" :idReception="idReception"
:disabled="!auth.isAdmin" :disabled="!auth.isAdmin"
/> />
<update-bovin
v-else
:idReception="idReception"
: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>({
@@ -249,7 +266,7 @@ const clearReceptionBovines = async (receptionIri: string) => {
} }
} }
const hydrateFromUser = (reception: ReceptionData | null)=> { const hydrateFromUser = (reception: ReceptionData | null) => {
if (!reception) { if (!reception) {
return return
} }
@@ -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,7 +412,11 @@ watch(
(address) => String(address.id) === form.addressId (address) => String(address.id) === form.addressId
) )
if (!matches) { if (!matches) {
form.addressId = '' if (supplierAddresses.value.length === 1) {
form.addressId = String(supplierAddresses.value[0].id)
} else {
form.addressId = ''
}
} }
}, },
{immediate: true} {immediate: true}
@@ -532,7 +553,7 @@ async function validate() {
} }
if (idReception) { if (idReception) {
const updated = await receptionStore.updateReception(idReception,{ const updated = await receptionStore.updateReception(idReception, {
...payload ...payload
}) })
if (updated) { if (updated) {

View File

@@ -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"

View File

@@ -2,4 +2,5 @@ export interface WeightData {
weight: number | null weight: number | null
dsd: number | null dsd: number | null
weighedAt: string | null weighedAt: string | null
type : string | null
} }

View File

@@ -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']],

View File

@@ -22,13 +22,10 @@ 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']],
),
new GetCollection(
uriTemplate: '/admin/suppliers',
normalizationContext: ['groups' => ['supplier:read']],
security: "is_granted('ROLE_ADMIN')" security: "is_granted('ROLE_ADMIN')"
), ),
new Post( new Post(

View File

@@ -21,8 +21,12 @@ final class UserPasswordProcessor implements ProcessorInterface
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed
{ {
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