Compare commits

..

2 Commits

Author SHA1 Message Date
548e5f3c17 Merge branch 'refs/heads/develop' into fix/325-corrections-diverses 2026-02-13 08:49:33 +01:00
e591a98c85 fix : corrections diverses 2026-02-12 17:09:22 +01:00
18 changed files with 194 additions and 616 deletions

10
.idea/data_source_mapping.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?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,10 +4,28 @@
<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="fix : corrections diverses"> <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)">
<change beforePath="$PROJECT_DIR$/.idea/data_source_mapping.xml" beforeDir="false" /> <change afterPath="$PROJECT_DIR$/frontend/components/shipment/shipment-form.vue" afterDir="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$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" /> <change beforePath="$PROJECT_DIR$/config/reference.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/reference.php" 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" />
@@ -32,21 +50,17 @@
<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="feat/276-lister-expeditions-terminees" /> <entry key="$PROJECT_DIR$" value="fix/makefile" />
</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 />
@@ -223,42 +237,37 @@
<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">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;RunOnceActivity.MCP Project settings loaded&quot;: &quot;true&quot;, "RunOnceActivity.MCP Project settings loaded": "true",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;, "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, "RunOnceActivity.git.unshallow": "true",
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;, "RunOnceActivity.typescript.service.memoryLimit.init": "true",
&quot;git-widget-placeholder&quot;: &quot;fix/325-corrections-diverses&quot;, "git-widget-placeholder": "feat/271-expedition-etape-1",
&quot;last_opened_file_path&quot;: &quot;//wsl.localhost/Ubuntu-24.04/home/kevin/Stage/Ferme/frontend/pages/shipment&quot;, "last_opened_file_path": "/home/sroy/Documents/test/Ferme",
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, "node.js.detected.package.eslint": "true",
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, "node.js.detected.package.tslint": "true",
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.eslint": "(autodetect)",
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;, "node.js.selected.package.tslint": "(autodetect)",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;, "nodejs_package_manager_path": "npm",
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;, "settings.editor.selected.configurable": "configurable.tailwindcss",
&quot;ts.external.directory.path&quot;: &quot;/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external&quot;, "ts.external.directory.path": "/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external",
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot; "vue.rearranger.settings.migration": "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"
] ]
} }
}</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" />
@@ -304,10 +313,54 @@
<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" />
<workItem from="1770798536017" duration="20774000" /> </task>
<workItem from="1770879701502" duration="25805000" /> <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="1770966186589" duration="914000" /> <option name="closed" value="true" />
<workItem from="1770967274060" duration="2388000" /> <created>1768237763998</created>
<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" />
@@ -653,55 +706,7 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1770217875423</updated> <updated>1770217875423</updated>
</task> </task>
<task id="LOCAL-00050" summary="feat : creer une nouvelle expedtion (WIP)"> <option name="localTasksCounter" value="50" />
<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">
@@ -751,6 +756,12 @@
</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" />
@@ -770,13 +781,7 @@
<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)" />
<MESSAGE value="feat : creer une nouvelle expedtion (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 : 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>
@@ -786,19 +791,10 @@
<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/dto/shipment-data.ts</url> <url>file://$PROJECT_DIR$/frontend/services/shipment.ts</url>
<option name="timeStamp" value="43" /> <properties lambdaOrdinal="-1" />
</line-breakpoint> <option name="timeStamp" value="37" />
<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,7 +45,6 @@ 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

@@ -1,2 +1,2 @@
parameters: parameters:
app.version: '0.0.45' app.version: '0.0.43'

View File

@@ -4,23 +4,29 @@
<UiTextInput <UiTextInput
label="Dsd" label="Dsd"
class="col-start-2" class="col-start-2"
v-model="sharedWeightMeta.dsd" v-model="form.weights[0].dsd"
:disabled="!auth.isAdmin" :disabled="!auth.isAdmin"
/> />
<UiDateInput <UiDateInput
label="Date pesée" label="Date pesée"
v-model="sharedWeightMeta.weighedAt" v-model="form.weights[0].weighedAt"
:disabled="!auth.isAdmin" :disabled="!auth.isAdmin"
/> />
</div> </div>
<div class="grid grid-cols-2 gap-x-40 mb-16"> <div class="grid grid-cols-2 gap-x-40 mb-16">
<UiNumberInput <UiNumberInput
v-for="weight in form.weights" label="Pesée à vide"
:key="weight.type"
:label="getWeightLabel(weight.type)"
labelClass="font-bold uppercase text-xl" labelClass="font-bold uppercase text-xl"
v-model="weight.weight" v-model="form.weights[0].weight"
:wrapper-class="weight.type === 'tare' ? 'col-start-1 row-start-1' : 'col-start-2 row-start-1'" wrapper-class="col-start-1 row-start-1"
:disabled="!auth.isAdmin"
/>
<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" :disabled="!auth.isAdmin"
/> />
</div> </div>
@@ -58,38 +64,13 @@ const form = reactive({
{id: 0, type: 'gross' as const, weight: 0, dsd: null, weighedAt: null} {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) => {
// On hydrate chaque ligne par son type (tare/gross), sans dépendre d'un index. const tare = reception.weights.find(weight => weight.type === 'tare')
for (const receptionWeight of reception.weights) { const gross = reception.weights.find(weight => weight.type === 'gross')
const formWeight = form.weights.find(weight => weight.type === receptionWeight.type)
if (formWeight) {
Object.assign(formWeight, receptionWeight)
}
}
// On récupère une valeur existante pour préremplir les champs partagés. if (tare) form.weights[0] = {...form.weights[0], ...tare}
const weightWithMeta = reception.weights.find(weight => if (gross) form.weights[1] = {...form.weights[1], ...gross}
(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 () => {
@@ -99,13 +80,14 @@ onMounted(async () => {
async function validate() { async function validate() {
const sharedDsd = const sharedDsd =
sharedWeightMeta.dsd === null || sharedWeightMeta.dsd === undefined || sharedWeightMeta.dsd === '' form.weights[0].dsd === null || form.weights[0].dsd === undefined || form.weights[0].dsd === ''
? null ? null
: Number(sharedWeightMeta.dsd) : Number(form.weights[0].dsd)
const sharedWeighedAt = const sharedWeighedAt =
sharedWeightMeta.weighedAt === null || sharedWeightMeta.weighedAt === undefined || sharedWeightMeta.weighedAt === '' form.weights[0].weighedAt === null || form.weights[0].weighedAt === undefined || form.weights[0].weighedAt === ''
? null ? null
: sharedWeightMeta.weighedAt : 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, { await updateWeight(weight.id, {

View File

@@ -49,7 +49,7 @@
label="Client" label="Client"
:options="customers.map((customer) => ({ :options="customers.map((customer) => ({
value: String(customer.id), value: String(customer.id),
label: customer.name || `Client #${customer.id}` label: customer.label
}))" }))"
:loading="isLoadingCustomers" :loading="isLoadingCustomers"
wrapper-class="col-start-1 row-start-5" wrapper-class="col-start-1 row-start-5"

View File

@@ -15,9 +15,8 @@
</div> </div>
<div class="grid grid-cols-2 gap-y-8 gap-x-80 mb-10 py-12"> <div class="grid grid-cols-2 gap-y-8 gap-x-80 mb-10 py-12">
<UiTextInput id="customer-name" v-model="form.name" label="Nom du client" :disabled="!auth.isAdmin"/> <UiTextInput id="customer-label" v-model="form.label" label="Nom du client" :disabled="!auth.isAdmin"/>
<UiTextInput id="customer-phone" v-model="form.phone" label="Téléphone" :disabled="!auth.isAdmin"/> <UiTextInput id="customer-code" v-model="form.code" label="Code" :disabled="!auth.isAdmin"/>
<UiTextInput id="customer-email" v-model="form.email" label="Email" :disabled="!auth.isAdmin"/>
</div> </div>
<div class="mx-24 mb-4 py-6 border-t border-black"></div> <div class="mx-24 mb-4 py-6 border-t border-black"></div>
@@ -95,9 +94,8 @@ const resolveId = (param: unknown) => {
const customerId = computed(() => resolveId(route.params.id)) const customerId = computed(() => resolveId(route.params.id))
const isLoading = ref(false) const isLoading = ref(false)
const form = reactive<CustomerFormData>({ const form = reactive<CustomerFormData>({
name: "", label: "",
phone: "", code: "",
email: "",
addresses: [], addresses: [],
}) })
@@ -124,9 +122,8 @@ const goToEditAddress = (addressId: number | null) => {
const hydrateFromCustomer = (customer: CustomerData | null) => { const hydrateFromCustomer = (customer: CustomerData | null) => {
if (!customer) return if (!customer) return
form.name = customer.name ?? "" form.label = customer.label ?? ""
form.phone = customer.phone ?? "" form.code = customer.code ?? ""
form.email = customer.email ?? ""
if (!Array.isArray(customer.addresses) || customer.addresses.length === 0) { if (!Array.isArray(customer.addresses) || customer.addresses.length === 0) {
form.addresses = [] form.addresses = []
return return
@@ -168,14 +165,12 @@ async function validate() {
isLoading.value = true isLoading.value = true
try { try {
const name = form.name.trim() const label = form.label.trim()
const phone = form.phone?.trim() || null const code = form.code.trim()
const email = form.email?.trim() || null
const customerPayload: CustomerPayload = { const customerPayload: CustomerPayload = {
name, label,
phone, code,
email,
} }
let targetId: number | null = null let targetId: number | null = null

View File

@@ -14,11 +14,10 @@
<div v-if="auth.isAdmin" class="mt-6 border border-slate-200 mb-16"> <div v-if="auth.isAdmin" class="mt-6 border border-slate-200 mb-16">
<div class="max-h-96 overflow-y-auto"> <div class="max-h-96 overflow-y-auto">
<div <div
class="sticky top-0 z-10 grid grid-cols-8 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide" class="sticky top-0 z-10 grid grid-cols-7 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide"
> >
<div>Nom</div> <div>Nom</div>
<div>Téléphone</div> <div>Code</div>
<div>Email</div>
<div>Rue</div> <div>Rue</div>
<div>Complément</div> <div>Complément</div>
<div>Code Postal</div> <div>Code Postal</div>
@@ -27,18 +26,17 @@
</div> </div>
<div v-if="customerList.length === 0" class="px-4 py-6 text-slate-400"> <div v-if="customerList.length === 0" class="px-4 py-6 text-slate-400">
Aucun client. Aucun fournisseur.
</div> </div>
<div v-for="customer in customerList" :key="customer.id"> <div v-for="customer in customerList" :key="customer.id">
<div <div
v-if="!customer.addresses || customer.addresses.length === 0" v-if="!customer.addresses || customer.addresses.length === 0"
class="grid grid-cols-8 border-t gap-4 px-4 py-2 hover:bg-slate-50 cursor-pointer" class="grid grid-cols-7 border-t gap-4 px-4 py-2 hover:bg-slate-50 cursor-pointer"
@click="goToCustomer(customer.id)" @click="goToCustomer(customer.id)"
> >
<div class="truncate">{{ customer.name || "—" }}</div> <div class="truncate">{{ customer.label }}</div>
<div class="truncate">{{ customer.phone || "—" }}</div> <div class="truncate">{{ customer.code }}</div>
<div class="truncate">{{ customer.email || "—" }}</div>
<div class="col-span-1">Pas d'adresse</div> <div class="col-span-1">Pas d'adresse</div>
<div class="uppercase truncate">{{"—"}}</div> <div class="uppercase truncate">{{"—"}}</div>
<div class="uppercase truncate">{{"—"}}</div> <div class="uppercase truncate">{{"—"}}</div>
@@ -50,15 +48,14 @@
<div <div
v-for="(address, idx) in customer.addresses" v-for="(address, idx) in customer.addresses"
:key="address.id ?? `${customer.id}-${idx}-${address.street}-${address.postalCode}`" :key="address.id ?? `${customer.id}-${idx}-${address.street}-${address.postalCode}`"
class="grid grid-cols-8 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer" class="grid grid-cols-7 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer"
:class="idx > 0 ? 'pl-4 border-l-4 border-l-slate-200 bg-slate-50' : ''" :class="idx > 0 ? 'pl-4 border-l-4 border-l-slate-200 bg-slate-50' : ''"
@click="goToCustomer(customer.id)" @click="goToCustomer(customer.id)"
> >
<div class="truncate"> <div class="truncate">
{{ idx === 0 ? (customer.name || "") : "" }} {{ idx === 0 ? customer.label : "" }}
</div> </div>
<div class="truncate">{{ idx === 0 ? (customer.phone || "") : "" }}</div> <div class="truncate">{{ idx === 0 ? customer.code : "" }}</div>
<div class="truncate">{{ idx === 0 ? (customer.email || "") : "" }}</div>
<div class="truncate">{{ address.street || "" }}</div> <div class="truncate">{{ address.street || "" }}</div>
<div class="truncate">{{ address.street2 || "" }}</div> <div class="truncate">{{ address.street2 || "" }}</div>
<div>{{ address.postalCode || "" }}</div> <div>{{ address.postalCode || "" }}</div>
@@ -69,12 +66,11 @@
<template v-else> <template v-else>
<div <div
class="grid grid-cols-8 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer" class="grid grid-cols-7 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer"
@click="goToCustomer(customer.id)" @click="goToCustomer(customer.id)"
> >
<div class="truncate">{{ customer.name || "" }}</div> <div class="truncate">{{ customer.label }}</div>
<div class="truncate">{{ customer.phone || "" }}</div> <div class="truncate">{{ customer.code }}</div>
<div class="truncate">{{ customer.email || "" }}</div>
<div class="col-span-5 text-slate-400"> <div class="col-span-5 text-slate-400">
Adresses non chargées Adresses non chargées
</div> </div>

View File

@@ -4,22 +4,19 @@ export type CustomerAddresses = AddressFormData[] | string[]
export interface CustomerData { export interface CustomerData {
id: number id: number
name: string label: string
phone?: string | null code?: string | null
email?: string | null
addresses: CustomerAddresses addresses: CustomerAddresses
} }
export interface CustomerFormData { export interface CustomerFormData {
name: string label: string
phone?: string code?: string
email?: string
addresses: AddressFormData[] addresses: AddressFormData[]
} }
export type CustomerPayload = { export type CustomerPayload = {
name: string label: string
phone?: string | null code?: string | null
email?: string | null
addresses?: string[] addresses?: string[]
} }

View File

@@ -2,5 +2,4 @@ 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

@@ -1,32 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20260213093000 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add name, phone and email fields to customer.';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE customer ADD name VARCHAR(255) DEFAULT NULL');
$this->addSql('ALTER TABLE customer ADD phone VARCHAR(255) DEFAULT NULL');
$this->addSql('ALTER TABLE customer ADD email VARCHAR(255) DEFAULT NULL');
$this->addSql('UPDATE customer SET name = label WHERE name IS NULL');
$this->addSql('ALTER TABLE customer ALTER COLUMN name SET NOT NULL');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE customer DROP name');
$this->addSql('ALTER TABLE customer DROP phone');
$this->addSql('ALTER TABLE customer DROP email');
}
}

View File

@@ -1,37 +0,0 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20260213101500 extends AbstractMigration
{
public function getDescription(): string
{
return 'Align customer with supplier: keep name/email/phone and drop label/code.';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE customer ALTER COLUMN name TYPE VARCHAR(180)');
$this->addSql('ALTER TABLE customer ALTER COLUMN email TYPE VARCHAR(180)');
$this->addSql('ALTER TABLE customer ALTER COLUMN phone TYPE VARCHAR(40)');
$this->addSql('ALTER TABLE customer DROP COLUMN label');
$this->addSql('ALTER TABLE customer DROP COLUMN code');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE customer ADD label VARCHAR(255) DEFAULT NULL');
$this->addSql('ALTER TABLE customer ADD code VARCHAR(255) DEFAULT NULL');
$this->addSql('UPDATE customer SET label = name WHERE label IS NULL');
$this->addSql("UPDATE customer SET code = regexp_replace(upper(name), '[^A-Z0-9]+', '_', 'g') WHERE code IS NULL");
$this->addSql('ALTER TABLE customer ALTER COLUMN label SET NOT NULL');
$this->addSql('ALTER TABLE customer ALTER COLUMN code SET NOT NULL');
$this->addSql('ALTER TABLE customer ALTER COLUMN email TYPE VARCHAR(255)');
$this->addSql('ALTER TABLE customer ALTER COLUMN phone TYPE VARCHAR(255)');
}
}

View File

@@ -5,15 +5,12 @@ declare(strict_types=1);
namespace App\Command; namespace App\Command;
use App\Entity\Address; use App\Entity\Address;
use App\Entity\BovineType;
use App\Entity\Building; use App\Entity\Building;
use App\Entity\Carrier; use App\Entity\Carrier;
use App\Entity\Customer;
use App\Entity\Driver; use App\Entity\Driver;
use App\Entity\MerchandiseType; use App\Entity\MerchandiseType;
use App\Entity\PelletType; use App\Entity\PelletType;
use App\Entity\ReceptionType; use App\Entity\ReceptionType;
use App\Entity\ShipmentType;
use App\Entity\Supplier; use App\Entity\Supplier;
use App\Entity\Truck; use App\Entity\Truck;
use App\Entity\Vehicle; use App\Entity\Vehicle;
@@ -53,11 +50,7 @@ class SeedCommand extends Command
$this->seedPelletTypes(); $this->seedPelletTypes();
$this->seedBuildings(); $this->seedBuildings();
$this->seedReceptionTypes(); $this->seedReceptionTypes();
$this->seedBovineTypes();
$this->seedShipmentTypes();
$this->seedSuppliers(); $this->seedSuppliers();
$this->entityManager->flush();
$this->seedCustomers($io);
$this->entityManager->flush(); $this->entityManager->flush();
@@ -68,7 +61,7 @@ class SeedCommand extends Command
private function seedTrucks(): array private function seedTrucks(): array
{ {
$trucks = ['Citerne', 'Porteur', 'Plateau', 'Remorque', 'Benne']; $trucks = ['Citerne', 'Porteur'];
$citerne = null; $citerne = null;
$porteur = null; $porteur = null;
foreach ($trucks as $name) { foreach ($trucks as $name) {
@@ -230,39 +223,6 @@ class SeedCommand extends Command
} }
} }
private function seedBovineTypes(): void
{
$bovineTypes = [
['label' => 'Limousine', 'code' => '34'],
['label' => 'Charolaise', 'code' => '38'],
['label' => 'Parthenaise', 'code' => '71'],
];
foreach ($bovineTypes as $type) {
$this->upsertByCode(BovineType::class, $type['code'], static function (BovineType $entity) use ($type) {
$entity
->setLabel($type['label'])
->setCode($type['code'])
;
});
}
}
private function seedShipmentTypes(): void
{
$shipmentTypes = [
['label' => 'Bovin de boucherie', 'code' => 'BDB'],
['label' => "Bovin d'équarrissage", 'code' => 'BE'],
];
foreach ($shipmentTypes as $type) {
$this->upsertByCode(ShipmentType::class, $type['code'], static function (ShipmentType $entity) use ($type) {
$entity
->setLabel($type['label'])
->setCode($type['code'])
;
});
}
}
private function seedSuppliers(): void private function seedSuppliers(): void
{ {
$suppliers = [ $suppliers = [
@@ -498,130 +458,6 @@ class SeedCommand extends Command
} }
} }
private function seedCustomers(SymfonyStyle $io): void
{
$addressRepo = $this->entityManager->getRepository(Address::class);
$customers = [
[
'name' => 'ARNAULT EURL',
'phone' => '05.49.02.65.27',
'email' => 'eurl.arnault86@orange.fr',
'addresses' => [
[
'label' => 'ARNAULT EURL',
'street' => 'Moulin du Guéret',
'street2' => 'B.P 30425',
'postalCode' => '86100',
'city' => 'Antran',
'countryCode' => 'FR',
],
],
],
[
'name' => 'COVILIM',
'phone' => '05.55.30.03.10',
'email' => 'sandra.robineaux@covilim.com',
'addresses' => [
[
'label' => 'COVILIM',
'street' => 'Rue de Nexon',
'street2' => null,
'postalCode' => '87000',
'city' => 'LIMOGES',
'countryCode' => 'FR',
],
],
],
[
'name' => 'Les producteurs de la marche (LPM)',
'phone' => '05.55.63.04.53',
'email' => 'f.legalliard@lpmcoop.fr',
'addresses' => [
[
'label' => 'Les producteurs de la marche (LPM)',
'street' => 'Rue de Nexon',
'street2' => null,
'postalCode' => '87000',
'city' => 'LIMOGES',
'countryCode' => 'FR',
],
],
],
[
'name' => 'LORTHOLARY BETAIL',
'phone' => '05.49.52.77.10',
'email' => 'contact86@lortholarybetail.com',
'addresses' => [
[
'label' => 'LORTHOLARY BETAIL',
'street' => 'FERME DE GENIEC',
'street2' => null,
'postalCode' => '86550',
'city' => 'MIGNALOUX BEAUVOIR',
'countryCode' => 'FR',
],
],
],
[
'name' => 'TERRENA',
'phone' => '02.51.67.17.98',
'email' => null,
'addresses' => [
[
'label' => 'TERRENA',
'street' => 'La Blanchardière',
'street2' => null,
'postalCode' => '44522',
'city' => 'MESANGER',
'countryCode' => 'FR',
],
],
],
];
foreach ($customers as $customerData) {
$customerName = $customerData['name'] ?? $customerData['label'] ?? null;
if (!$customerName) {
$io->warning('Customer skipped: missing "name".');
continue;
}
$customer = $this->upsertByName(Customer::class, $customerName, static function (Customer $customer) use ($customerData, $customerName) {
$customer
->setName($customerName)
->setPhone($customerData['phone'] ?? null)
->setEmail($customerData['email'] ?? null)
;
});
$addresses = [];
if (isset($customerData['addresses']) && is_array($customerData['addresses'])) {
foreach ($customerData['addresses'] as $addressData) {
$addresses[] = $this->upsertAddress($addressData);
}
} else {
// Backward compatibility for older seed format with address ids.
$addressIds = $customerData['addressIds'] ?? (isset($customerData['addressId']) ? [$customerData['addressId']] : []);
foreach ($addressIds as $addressId) {
$address = $addressRepo->find($addressId);
if (!$address instanceof Address) {
$io->warning(sprintf(
'Customer "%s" skipped address id %d: not found.',
$customerName,
$addressId
));
continue;
}
$addresses[] = $address;
}
}
$customer->setAddresses($addresses);
$this->entityManager->persist($customer);
}
}
private function upsertByCode(string $entityClass, string $code, callable $apply): object private function upsertByCode(string $entityClass, string $code, callable $apply): object
{ {
$repo = $this->entityManager->getRepository($entityClass); $repo = $this->entityManager->getRepository($entityClass);

View File

@@ -20,6 +20,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
return [ return [
TransportFixtures::class, TransportFixtures::class,
ReferenceFixtures::class, ReferenceFixtures::class,
SupplierFixtures::class,
UserFixtures::class, UserFixtures::class,
]; ];
} }

View File

@@ -5,13 +5,10 @@ declare(strict_types=1);
namespace App\DataFixtures; namespace App\DataFixtures;
use App\Entity\Address; use App\Entity\Address;
use App\Entity\BovineType;
use App\Entity\Building; use App\Entity\Building;
use App\Entity\Customer;
use App\Entity\MerchandiseType; use App\Entity\MerchandiseType;
use App\Entity\PelletType; use App\Entity\PelletType;
use App\Entity\ReceptionType; use App\Entity\ReceptionType;
use App\Entity\ShipmentType;
use App\Entity\Supplier; use App\Entity\Supplier;
use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager; use Doctrine\Persistence\ObjectManager;
@@ -20,8 +17,6 @@ class ReferenceFixtures extends Fixture
{ {
public function load(ObjectManager $manager): void public function load(ObjectManager $manager): void
{ {
$addressIndex = [];
$merchandiseTypes = [ $merchandiseTypes = [
['label' => 'Foin', 'code' => 'FOIN'], ['label' => 'Foin', 'code' => 'FOIN'],
['label' => 'Paille', 'code' => 'PAILLE'], ['label' => 'Paille', 'code' => 'PAILLE'],
@@ -74,31 +69,6 @@ class ReferenceFixtures extends Fixture
$manager->persist($receptionType); $manager->persist($receptionType);
} }
$bovineTypes = [
['label' => 'Limousine', 'code' => '34'],
['label' => 'Charolaise', 'code' => '38'],
['label' => 'Parthenaise', 'code' => '71'],
];
foreach ($bovineTypes as $type) {
$bovineType = new BovineType()
->setLabel($type['label'])
->setCode($type['code'])
;
$manager->persist($bovineType);
}
$shipmentTypes = [
['label' => 'Bovin de boucherie', 'code' => 'BDB'],
['label' => "Bovin d'équarrissage", 'code' => 'BE'],
];
foreach ($shipmentTypes as $type) {
$shipmentType = new ShipmentType()
->setLabel($type['label'])
->setCode($type['code'])
;
$manager->persist($shipmentType);
}
$suppliers = [ $suppliers = [
[ [
'name' => 'LIOT', 'name' => 'LIOT',
@@ -320,129 +290,21 @@ class ReferenceFixtures extends Fixture
; ;
foreach ($supplierData['addresses'] as $addressData) { foreach ($supplierData['addresses'] as $addressData) {
$addressKey = sprintf('%s|%s', $addressData['label'], $addressData['postalCode']); $address = new Address()
if (!isset($addressIndex[$addressKey])) { ->setLabel($addressData['label'])
$addressIndex[$addressKey] = new Address() ->setStreet($addressData['street'])
->setLabel($addressData['label']) ->setStreet2($addressData['street2'])
->setStreet($addressData['street']) ->setPostalCode($addressData['postalCode'])
->setStreet2($addressData['street2']) ->setCity($addressData['city'])
->setPostalCode($addressData['postalCode']) ->setCountryCode($addressData['countryCode'])
->setCity($addressData['city']) ;
->setCountryCode($addressData['countryCode']) $manager->persist($address);
;
$manager->persist($addressIndex[$addressKey]);
}
$address = $addressIndex[$addressKey];
$supplier->getAddresses()->add($address); $supplier->getAddresses()->add($address);
} }
$manager->persist($supplier); $manager->persist($supplier);
} }
$customers = [
[
'name' => 'ARNAULT EURL',
'phone' => '05.49.02.65.27',
'email' => 'eurl.arnault86@orange.fr',
'addresses' => [
[
'label' => 'ARNAULT EURL',
'street' => 'Moulin du Guéret',
'street2' => 'B.P 30425',
'postalCode' => '86100',
'city' => 'Antran',
'countryCode' => 'FR',
],
],
],
[
'name' => 'COVILIM',
'phone' => '05.55.30.03.10',
'email' => 'sandra.robineaux@covilim.com',
'addresses' => [
[
'label' => 'COVILIM',
'street' => 'Rue de Nexon',
'street2' => null,
'postalCode' => '87000',
'city' => 'LIMOGES',
'countryCode' => 'FR',
],
],
],
[
'name' => 'Les producteurs de la marche (LPM)',
'phone' => '05.55.63.04.53',
'email' => 'f.legalliard@lpmcoop.fr',
'addresses' => [
[
'label' => 'Les producteurs de la marche (LPM)',
'street' => 'Rue de Nexon',
'street2' => null,
'postalCode' => '87000',
'city' => 'LIMOGES',
'countryCode' => 'FR',
],
],
],
[
'name' => 'LORTHOLARY BETAIL',
'phone' => '05.49.52.77.10',
'email' => 'contact86@lortholarybetail.com',
'addresses' => [
[
'label' => 'LORTHOLARY BETAIL',
'street' => 'FERME DE GENIEC',
'street2' => null,
'postalCode' => '86550',
'city' => 'MIGNALOUX BEAUVOIR',
'countryCode' => 'FR',
],
],
],
[
'name' => 'TERRENA',
'phone' => '02.51.67.17.98',
'email' => null,
'addresses' => [
[
'label' => 'TERRENA',
'street' => 'La Blanchardière',
'street2' => null,
'postalCode' => '44522',
'city' => 'MESANGER',
'countryCode' => 'FR',
],
],
],
];
foreach ($customers as $customerData) {
$customer = new Customer()
->setName($customerData['name'])
->setPhone($customerData['phone'])
->setEmail($customerData['email'])
;
foreach ($customerData['addresses'] as $addressData) {
$addressKey = sprintf('%s|%s', $addressData['label'], $addressData['postalCode']);
if (!isset($addressIndex[$addressKey])) {
$addressIndex[$addressKey] = new Address()
->setLabel($addressData['label'])
->setStreet($addressData['street'])
->setStreet2($addressData['street2'])
->setPostalCode($addressData['postalCode'])
->setCity($addressData['city'])
->setCountryCode($addressData['countryCode'])
;
$manager->persist($addressIndex[$addressKey]);
}
$customer->getAddresses()->add($addressIndex[$addressKey]);
}
$manager->persist($customer);
}
$manager->flush(); $manager->flush();
} }
} }

View File

@@ -15,17 +15,11 @@ class TransportFixtures extends Fixture
{ {
public function load(ObjectManager $manager): void public function load(ObjectManager $manager): void
{ {
$citerne = new Truck()->setName('Citerne'); $citerne = new Truck()->setName('Citerne');
$porteur = new Truck()->setName('Porteur'); $porteur = new Truck()->setName('Porteur');
$plateau = new Truck()->setName('Plateau');
$remorque = new Truck()->setName('Remorque');
$benne = new Truck()->setName('Benne');
$manager->persist($citerne); $manager->persist($citerne);
$manager->persist($porteur); $manager->persist($porteur);
$manager->persist($plateau);
$manager->persist($remorque);
$manager->persist($benne);
$liot = new Carrier() $liot = new Carrier()
->setName('LIOT') ->setName('LIOT')

View File

@@ -47,17 +47,13 @@ class Customer
#[Groups(['shipment:read', 'customer:read'])] #[Groups(['shipment:read', 'customer:read'])]
private ?int $id = null; private ?int $id = null;
#[ORM\Column(length: 180)] #[ORM\Column(length: 255)]
#[Groups(['customer:read', 'customer:write', 'shipment:read'])] #[Groups(['customer:read', 'customer:write', 'shipment:read'])]
private string $name = ''; private ?string $label = null;
#[ORM\Column(length: 180, nullable: true)] #[ORM\Column(length: 255)]
#[Groups(['customer:read', 'customer:write', 'shipment:read'])] #[Groups(['customer:read', 'customer:write', 'shipment:read'])]
private ?string $email = null; private ?string $code = null;
#[ORM\Column(length: 40, nullable: true)]
#[Groups(['customer:read', 'customer:write', 'shipment:read'])]
private ?string $phone = null;
/** /**
* @var Collection<int, Address> * @var Collection<int, Address>
@@ -78,40 +74,24 @@ class Customer
return $this->id; return $this->id;
} }
public function getName(): string public function getLabel(): ?string
{ {
return $this->name; return $this->label;
} }
public function setName(string $name): self public function setLabel(?string $label): void
{ {
$this->name = $name; $this->label = $label;
return $this;
} }
public function getEmail(): ?string public function getCode(): ?string
{ {
return $this->email; return $this->code;
} }
public function setEmail(?string $email): self public function setCode(?string $code): void
{ {
$this->email = $email; $this->code = $code;
return $this;
}
public function getPhone(): ?string
{
return $this->phone;
}
public function setPhone(?string $phone): self
{
$this->phone = $phone;
return $this;
} }
public function getAddresses(): Collection public function getAddresses(): Collection

View File

@@ -26,7 +26,7 @@ use Symfony\Component\Serializer\Attribute\Groups;
), ),
new GetCollection( new GetCollection(
normalizationContext: ['groups' => ['supplier:read']], normalizationContext: ['groups' => ['supplier:read']],
security: "is_granted('ROLE_ADMIN')" security: "is_granted('ROLE_USER')"
), ),
new Post( new Post(
normalizationContext: ['groups' => ['supplier:read']], normalizationContext: ['groups' => ['supplier:read']],