Compare commits

...

6 Commits

Author SHA1 Message Date
gitea-actions
fee7bbb2ec chore: bump version to v0.0.77
All checks were successful
Auto Tag Develop / tag (push) Successful in 6s
Build Release Artefact / build (push) Successful in 1m47s
2026-03-24 07:33:27 +00:00
b707aae0e8 fix : bouton de mise en attente
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
2026-03-24 08:33:13 +01:00
gitea-actions
d0beb80199 chore: bump version to v0.0.76
All checks were successful
Auto Tag Develop / tag (push) Successful in 6s
Build Release Artefact / build (push) Successful in 1m40s
2026-03-23 17:04:21 +00:00
c378b402c4 fix : style bon de récéption
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
2026-03-23 18:04:09 +01:00
gitea-actions
6e707484a0 chore: bump version to v0.0.75
All checks were successful
Auto Tag Develop / tag (push) Successful in 4s
Build Release Artefact / build (push) Successful in 1m22s
2026-03-23 16:26:46 +00:00
0067e51e6e fix : order récéption/expédition + correction style bouton récéption
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
2026-03-23 17:26:29 +01:00
14 changed files with 161 additions and 56 deletions

View File

@@ -2,7 +2,9 @@
"permissions": {
"allow": [
"Bash(npm run:*)",
"WebFetch(domain:geo.api.gouv.fr)"
"WebFetch(domain:geo.api.gouv.fr)",
"Bash(pip3 install:*)",
"Bash(python3 -c \":*)"
]
}
}

79
.idea/workspace.xml generated
View File

@@ -4,12 +4,17 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="fix : script de déploiement + CI/CD build de l'app">
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="fix : style bon de récéption">
<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$/frontend/layouts/default.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/layouts/default.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/pages/admin/customer/[[id]].vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/admin/customer/[[id]].vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/pages/admin/supplier/[[id]].vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/admin/supplier/[[id]].vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/components/reception/reception-form.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/reception/reception-form.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/components/shipment/shipment-form.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/shipment/shipment-form.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/components/workflow/workflow-weight.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/workflow/workflow-weight.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/composables/steps/useWeighingStep.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/composables/steps/useWeighingStep.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/composables/useWeighing.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/composables/useWeighing.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/composables/useWorkflowSteps.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/composables/useWorkflowSteps.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/pages/reception/[[id]].vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/reception/[[id]].vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/pages/shipment/[[id]].vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/shipment/[[id]].vue" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -264,8 +269,8 @@
<recent name="\\wsl.localhost\Ubuntu-24.04\home\kevin\Stage\Ferme\frontend\components\shipment" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="C:\Users\m-tristan\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches" />
<recent name="\\wsl.localhost\Ubuntu-24.04\home\m-tristan\workspace\Ferme" />
<recent name="C:\Users\m-tristan\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches" />
<recent name="\\wsl.localhost\Ubuntu-24.04\home\tristan\workspace\ferme\templates" />
<recent name="C:\Users\autin\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches" />
<recent name="C:\Users\autin\AppData\Roaming\JetBrains\PhpStorm2025.3\scratches\Ferme_MCD\MCD_DOC" />
@@ -274,7 +279,7 @@
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-php-predefined-a98d8de5180a-0e0d91225499-com.jetbrains.php.sharedIndexes-PS-253.31033.138" />
<option value="bundled-php-predefined-a98d8de5180a-0e0d91225499-com.jetbrains.php.sharedIndexes-PS-253.32098.40" />
</set>
</attachedChunks>
</component>
@@ -324,31 +329,9 @@
<workItem from="1773215356754" duration="5754000" />
<workItem from="1773756072697" duration="5450000" />
<workItem from="1773766075191" duration="6202000" />
<workItem from="1773824491213" duration="20110000" />
</task>
<task id="LOCAL-00027" summary="fix : doc et script de déploiement">
<option name="closed" value="true" />
<created>1769096187792</created>
<option name="number" value="00027" />
<option name="presentableId" value="LOCAL-00027" />
<option name="project" value="LOCAL" />
<updated>1769096187792</updated>
</task>
<task id="LOCAL-00028" summary="fix : doc et script de déploiement">
<option name="closed" value="true" />
<created>1769097091268</created>
<option name="number" value="00028" />
<option name="presentableId" value="LOCAL-00028" />
<option name="project" value="LOCAL" />
<updated>1769097091268</updated>
</task>
<task id="LOCAL-00029" summary="fix : gitea workflow">
<option name="closed" value="true" />
<created>1769097476629</created>
<option name="number" value="00029" />
<option name="presentableId" value="LOCAL-00029" />
<option name="project" value="LOCAL" />
<updated>1769097476629</updated>
<workItem from="1773824491213" duration="24805000" />
<workItem from="1774275549972" duration="51000" />
<workItem from="1774276665015" duration="7447000" />
</task>
<task id="LOCAL-00030" summary="fix : script de déploiement">
<option name="closed" value="true" />
@@ -718,7 +701,31 @@
<option name="project" value="LOCAL" />
<updated>1773843922377</updated>
</task>
<option name="localTasksCounter" value="76" />
<task id="LOCAL-00076" summary="fix : order navbar + modification création fournisseur et client">
<option name="closed" value="true" />
<created>1773852806120</created>
<option name="number" value="00076" />
<option name="presentableId" value="LOCAL-00076" />
<option name="project" value="LOCAL" />
<updated>1773852806121</updated>
</task>
<task id="LOCAL-00077" summary="fix : order récéption/expédition + correction style bouton récéption">
<option name="closed" value="true" />
<created>1774283204849</created>
<option name="number" value="00077" />
<option name="presentableId" value="LOCAL-00077" />
<option name="project" value="LOCAL" />
<updated>1774283204849</updated>
</task>
<task id="LOCAL-00078" summary="fix : style bon de récéption">
<option name="closed" value="true" />
<created>1774285464091</created>
<option name="number" value="00078" />
<option name="presentableId" value="LOCAL-00078" />
<option name="project" value="LOCAL" />
<updated>1774285464091</updated>
</task>
<option name="localTasksCounter" value="79" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -768,9 +775,6 @@
</option>
</component>
<component name="VcsManagerConfiguration">
<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 : 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" />
@@ -793,7 +797,10 @@
<MESSAGE value="fix : correction des retours de la V0" />
<MESSAGE value="feat : ajout de l'api de l'état pour chercher les villes via le CP" />
<MESSAGE value="fix : script de déploiement + CI/CD build de l'app" />
<option name="LAST_COMMIT_MESSAGE" value="fix : script de déploiement + CI/CD build de l'app" />
<MESSAGE value="fix : order navbar + modification création fournisseur et client" />
<MESSAGE value="fix : order récéption/expédition + correction style bouton récéption" />
<MESSAGE value="fix : style bon de récéption" />
<option name="LAST_COMMIT_MESSAGE" value="fix : style bon de récéption" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>

View File

@@ -1,2 +1,2 @@
parameters:
app.version: '0.0.74'
app.version: '0.0.77'

View File

@@ -1,5 +1,5 @@
<template>
<form :class="{ submitted }" @submit.prevent="validate">
<form ref="formRef" :class="{ submitted }" @submit.prevent="validate">
<div class="grid grid-cols-2 items-start gap-y-8 gap-x-40 mb-16">
<h1 class="font-bold text-5xl uppercase col-start-1 row-start-1 text-primary-500">Réception</h1>
<UiSelect
@@ -116,7 +116,7 @@
<div class="flex justify-center">
<UiButton
type="submit"
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
class="text-xl mb-16 uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
@click="submitted = true"
>Valider
</UiButton>
@@ -141,6 +141,7 @@ const router = useRouter()
const receptionStore = useReceptionStore()
const isHydrating = ref(false)
const submitted = ref(false)
const formRef = ref<HTMLFormElement | null>(null)
const form = reactive<ReceptionFormData>({
licensePlate: '',
@@ -217,7 +218,7 @@ onMounted(async () => {
await loadVehicles()
})
async function validate() {
const buildPayload = () => {
const normalizedLicensePlate = form.licensePlate.trim()
const normalizedReceptionDate = form.receptionDate.trim()
const normalizedReceptionTypeId = form.receptionTypeId.trim()
@@ -236,7 +237,7 @@ async function validate() {
const carrierIri = normalizedCarrierId ? `/api/carriers/${normalizedCarrierId}` : null
const driverIri = normalizedDriverId ? `/api/drivers/${normalizedDriverId}` : null
const basePayload = {
return {
licensePlate: normalizedLicensePlate,
receptionDate: normalizedReceptionDate,
receptionType: receptionTypeIri,
@@ -244,13 +245,35 @@ async function validate() {
supplier: supplierIri,
address: addressIri,
truck: truckIri,
carrier: carrierIri
}
const payload = {
...basePayload,
carrier: carrierIri,
...(isLiotCarrier.value && driverIri ? { driver: driverIri } : {})
}
}
const saveDraft = async () => {
const payload = buildPayload()
if (!receptionStore.current) {
await receptionStore.createReception({
currentStep: 0,
...payload
})
return
}
await receptionStore.updateReception(receptionStore.current.id, {
currentStep: receptionStore.current.currentStep,
...payload
})
}
const validateFields = () => {
submitted.value = true
return formRef.value?.reportValidity() ?? false
}
defineExpose({ saveDraft, validateFields })
async function validate() {
const payload = buildPayload()
if (!receptionStore.current) {
const created = await receptionStore.createReception({

View File

@@ -1,5 +1,5 @@
<template>
<form :class="{ submitted }" @submit.prevent="validate">
<form ref="formRef" :class="{ submitted }" @submit.prevent="validate">
<div class="grid grid-cols-2 h-[461px] items-start gap-y-8 gap-x-40 mb-16">
<h1 class="font-bold text-5xl uppercase col-start-1 row-start-1 text-primary-500">Expédition</h1>
<UiSelect
@@ -152,6 +152,7 @@ const router = useRouter()
const shipmentStore = useShipmentStore()
const isHydrating = ref(false)
const submitted = ref(false)
const formRef = ref<HTMLFormElement | null>(null)
const form = reactive<ShipmentFormData>({
userId: '',
@@ -286,7 +287,12 @@ const saveDraft = async () => {
})
}
defineExpose({ saveDraft })
const validateFields = () => {
submitted.value = true
return formRef.value?.reportValidity() ?? false
}
defineExpose({ saveDraft, validateFields })
const validate = async () => {
const payload = buildPayload()

View File

@@ -60,6 +60,7 @@ const {
title,
fetchWeight,
saveWeight,
saveWeightDraft,
showGenerateReceipt,
printReceipt
} = useWeighingStep({
@@ -75,4 +76,6 @@ const {
clearEntity: props.clearEntity,
buildReceiptFilename: props.buildReceiptFilename
})
defineExpose({ saveWeightDraft })
</script>

View File

@@ -29,7 +29,8 @@ export const useWeighingStep = (options: UseWeighingStepOptions) => {
title,
showLoadingBox,
fetchWeight,
saveWeight
saveWeight,
saveWeightDraft
} = useWeighing({
mode: options.mode,
entity: options.entity,
@@ -71,6 +72,7 @@ export const useWeighingStep = (options: UseWeighingStepOptions) => {
showLoadingBox,
fetchWeight,
saveWeight,
saveWeightDraft,
showGenerateReceipt,
printReceipt
}

View File

@@ -90,6 +90,38 @@ export const useWeighing = ({
}
}
const saveWeightDraft = async () => {
if (!entity.value) return
if (!weightData.value && !currentWeightEntry.value) return
const existingEntry = currentWeightEntry.value
const baseDsd = weightData.value?.dsd ?? existingEntry?.dsd ?? null
const baseWeight = weightData.value?.weight ?? existingEntry?.weight ?? null
const baseWeighedAt = weightData.value?.weighedAt ?? existingEntry?.weighedAt ?? null
if (baseWeight === null) return
const relationPayload: Record<string, string> = {}
relationPayload[entityName] = `/api/${apiResource}/${entity.value.id}`
if (existingEntry?.id) {
await updateWeight(existingEntry.id, {
type: mode,
dsd: baseDsd,
weight: baseWeight,
weighedAt: baseWeighedAt
})
} else {
await createWeight({
...relationPayload,
type: mode,
dsd: baseDsd,
weight: baseWeight,
weighedAt: baseWeighedAt
})
}
}
return {
weightData,
currentWeightEntry,
@@ -98,7 +130,8 @@ export const useWeighing = ({
title,
showLoadingBox,
fetchWeight,
saveWeight
saveWeight,
saveWeightDraft
}
}

View File

@@ -48,7 +48,8 @@ export const useWorkflowSteps = (config: WorkflowConfig, store: WorkflowStore) =
return
}
const datePayload: Record<string, any> = {}
datePayload[config.dateField] = store.current[config.dateField]
const rawDate = store.current[config.dateField]
datePayload[config.dateField] = rawDate ? rawDate.slice(0, 10) : rawDate
await store[updateMethod](store.current.id, {
currentStep: store.current.currentStep,
licensePlate: store.current.licensePlate,

View File

@@ -14,9 +14,10 @@
>Mettre en attente
</UiButton>
</div>
<ReceptionForm v-if="!storeReception || storeReception.currentStep === 0"/>
<ReceptionForm v-if="!storeReception || storeReception.currentStep === 0" ref="receptionFormRef"/>
<WorkflowWeight
v-if="storeReception?.currentStep === 1"
ref="grossWeightRef"
mode="gross"
entity-name="reception"
api-resource="receptions"
@@ -37,6 +38,7 @@
receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.BOVINS"/>
<WorkflowWeight
v-if="storeReception?.currentStep !== null && storeReception?.currentStep >= 3"
ref="tareWeightRef"
mode="tare"
entity-name="reception"
api-resource="receptions"
@@ -61,8 +63,24 @@ import { RECEPTION_TYPE_CODES } from '~/utils/constants'
const receptionStore = useReceptionStore()
const { current: storeReception } = storeToRefs(receptionStore)
const receptionFormRef = ref<{ saveDraft: () => Promise<void>, validateFields: () => boolean } | null>(null)
const grossWeightRef = ref<{ saveWeightDraft: () => Promise<void> } | null>(null)
const tareWeightRef = ref<{ saveWeightDraft: () => Promise<void> } | null>(null)
const { stepLabels, saveAndHold, handleStepSelect } = useWorkflowSteps(receptionConfig, receptionStore)
const { stepLabels, handleStepSelect } = useWorkflowSteps(receptionConfig, receptionStore)
const router = useRouter()
const saveAndHold = async () => {
if (receptionFormRef.value) {
if (!receptionFormRef.value.validateFields()) return
await receptionFormRef.value.saveDraft()
} else {
if (grossWeightRef.value) await grossWeightRef.value.saveWeightDraft()
if (tareWeightRef.value) await tareWeightRef.value.saveWeightDraft()
}
await router.push('/')
}
// Init route watcher
const route = useRoute()

View File

@@ -18,6 +18,7 @@
<ShipmentForm v-if="!storeShipment || storeShipment.currentStep === 0" ref="shipmentFormRef"/>
<WorkflowWeight
v-if="storeShipment?.currentStep === 1"
ref="grossWeightRef"
mode="gross"
entity-name="shipment"
api-resource="shipments"
@@ -33,6 +34,7 @@
<ShipmentLoading v-if="storeShipment?.currentStep === 2"/>
<WorkflowWeight
v-if="storeShipment?.currentStep === 3"
ref="tareWeightRef"
mode="tare"
entity-name="shipment"
api-resource="shipments"
@@ -58,7 +60,9 @@ import { ref, watch } from 'vue'
const shipmentStore = useShipmentStore()
const { current: storeShipment } = storeToRefs(shipmentStore)
const shipmentFormRef = ref<{ saveDraft: () => Promise<void> } | null>(null)
const shipmentFormRef = ref<{ saveDraft: () => Promise<void>, validateFields: () => boolean } | null>(null)
const grossWeightRef = ref<{ saveWeightDraft: () => Promise<void> } | null>(null)
const tareWeightRef = ref<{ saveWeightDraft: () => Promise<void> } | null>(null)
const { stepLabels, handleStepSelect } = useWorkflowSteps(shipmentConfig, shipmentStore)
@@ -83,7 +87,11 @@ watch(
const saveAndHold = async () => {
if (shipmentFormRef.value) {
if (!shipmentFormRef.value.validateFields()) return
await shipmentFormRef.value.saveDraft()
} else {
if (grossWeightRef.value) await grossWeightRef.value.saveWeightDraft()
if (tareWeightRef.value) await tareWeightRef.value.saveWeightDraft()
}
await router.push('/')
}

View File

@@ -31,6 +31,7 @@ use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
#[ORM\Table(name: 'reception')]
#[ApiFilter(BooleanFilter::class, properties: ['isValid'])]
#[ApiResource(
order: ['id' => 'DESC'],
operations: [
new Get(
requirements: ['id' => '\d+'],

View File

@@ -31,6 +31,7 @@ use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
#[ORM\Table(name: 'shipment')]
#[ApiFilter(BooleanFilter::class, properties: ['isValid'])]
#[ApiResource(
order: ['id' => 'DESC'],
operations: [
new Get(
requirements: ['id' => '\d+'],

View File

@@ -140,7 +140,7 @@
</td>
<td style="width:30%; text-align:right; vertical-align:top; font-size: 14px;">
<div style="display:inline-block; width:75mm; line-height:1.3;">
<div style="display:inline-block; line-height:1.3; border: 1px solid black; padding: 8px; border-radius: 8px; width: 60mm">
<strong>{{ reception.supplier ? reception.supplier.name : '-' }}</strong><br>
<span>{{ reception.address ? reception.address.street : '' }}</span><br>
{% if reception.address and reception.address.street2 %}