Compare commits
5 Commits
v0.0.32
...
ba4375f609
| Author | SHA1 | Date | |
|---|---|---|---|
| ba4375f609 | |||
| e249d44e78 | |||
| e8189a4d04 | |||
| 081c2ef403 | |||
| 5fd2ab8470 |
@@ -16,50 +16,30 @@ jobs:
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Create next tag from config/version.yaml
|
||||
- name: Create next tag v0.0.X
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# Skip if current commit already has a vX.Y.Z tag
|
||||
if git tag --points-at HEAD | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
# Skip if current commit already has a v0.0.* tag
|
||||
if git tag --points-at HEAD | grep -qE '^v0\.0\.'; then
|
||||
echo "Tag already exists on this commit. Skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
changed_version=false
|
||||
if git diff --name-only "${{ gitea.event.before }}" "${{ gitea.event.after }}" | grep -q '^config/version\.yaml$'; then
|
||||
changed_version=true
|
||||
fi
|
||||
|
||||
read_version() {
|
||||
awk -F': *' '/app\.version:/{print $2}' config/version.yaml | tr -d '[:space:]' | tr -d "'\""
|
||||
}
|
||||
|
||||
if $changed_version; then
|
||||
version="$(read_version)"
|
||||
if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Invalid version in version.yaml: $version" >&2
|
||||
last_tag="$(git tag -l 'v0.0.*' --sort=-v:refname | head -n1 || true)"
|
||||
if [ -z "$last_tag" ]; then
|
||||
next_tag="v0.0.1"
|
||||
else
|
||||
patch="${last_tag##v0.0.}"
|
||||
if ! [[ "$patch" =~ ^[0-9]+$ ]]; then
|
||||
echo "Unexpected tag format: $last_tag" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
last_tag="$(git tag -l 'v*' --sort=-v:refname | head -n1 || true)"
|
||||
if [ -z "$last_tag" ]; then
|
||||
version="0.1.0"
|
||||
else
|
||||
base="${last_tag#v}"
|
||||
IFS='.' read -r major minor patch <<< "$base"
|
||||
version="${major}.${minor}.$((patch + 1))"
|
||||
fi
|
||||
|
||||
printf "parameters:\\n app.version: '%s'\\n" "$version" > config/version.yaml
|
||||
git config user.name "gitea-actions"
|
||||
git config user.email "gitea-actions@local"
|
||||
git add config/version.yaml
|
||||
git commit -m "chore: bump version to v$version" || true
|
||||
git push origin develop || true
|
||||
next_tag="v0.0.$((patch + 1))"
|
||||
fi
|
||||
|
||||
tag="v$version"
|
||||
git tag "$tag"
|
||||
git push origin "$tag"
|
||||
git config user.name "gitea-actions"
|
||||
git config user.email "gitea-actions@local"
|
||||
git tag "$next_tag"
|
||||
git push origin "$next_tag"
|
||||
|
||||
2
.idea/dataSources.xml
generated
2
.idea/dataSources.xml
generated
@@ -16,4 +16,4 @@
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
</project>
|
||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
6
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PhpCSFixerValidationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
1
.idea/php.xml
generated
1
.idea/php.xml
generated
@@ -15,6 +15,7 @@
|
||||
<component name="PhpCSFixer">
|
||||
<phpcsfixer_settings>
|
||||
<PhpCSFixerConfiguration tool_path="$PROJECT_DIR$/vendor/bin/php-cs-fixer" />
|
||||
<phpcs_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="990ff521-e6e9-4080-9cc9-228367d597f9" tool_path="\\wsl.localhost\Ubuntu-24.04\home\matte\Ferme\vendor\bin\php-cs-fixer" timeout="30000" />
|
||||
</phpcsfixer_settings>
|
||||
</component>
|
||||
<component name="PhpCodeSniffer">
|
||||
|
||||
267
.idea/workspace.xml
generated
267
.idea/workspace.xml
generated
@@ -4,16 +4,20 @@
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="feat : test auto-tag-develop.yml (auto incrément version)">
|
||||
<change afterPath="$PROJECT_DIR$/frontend/composables/useAppVersion.ts" afterDir="false" />
|
||||
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="feat : Expedition dev back-end">
|
||||
<change afterPath="$PROJECT_DIR$/migrations/Version20260204101625.php" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/migrations/Version20260204102423.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/config/packages/security.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/config/packages/security.yaml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/config/reference.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/reference.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/frontend/app.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/app.vue" 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/login.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/pages/login.vue" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Dto/AppVersion.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/ApiResource/AppVersion.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/State/AppVersionProvider.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/State/AppVersionProvider.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/makefile" beforeDir="false" afterPath="$PROJECT_DIR$/makefile" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/migrations/Version20260203152543.php" beforeDir="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/BovineTypeShipment.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/ShipmentType.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Entity/Carrier.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/Carrier.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Entity/Customer.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/Customer.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Entity/Shipment.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/Shipment.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Entity/Vehicle.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/Vehicle.php" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -26,29 +30,31 @@
|
||||
</component>
|
||||
<component name="CopilotPersistence">
|
||||
<persistenceIdMap>
|
||||
<entry key="_//wsl.localhost/Ubuntu-24.04/home/kevin/Stage/Ferme" value="381AhnCm9yPeOiWgMObKHhtgv2C" />
|
||||
<entry key="_//wsl.localhost/Ubuntu-24.04/home/matte/Ferme" value="381AhnCm9yPeOiWgMObKHhtgv2C" />
|
||||
</persistenceIdMap>
|
||||
</component>
|
||||
<component name="EmbeddingIndexingInfo">
|
||||
<option name="cachedIndexableFilesCount" value="151" />
|
||||
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Vue Composition API Component" />
|
||||
<option value="TypeScript File" />
|
||||
<option value="Vue Composition API Component" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$" value="feat/256-reception-etape-3-bovin" />
|
||||
<entry key="$PROJECT_DIR$" value="fix/makefile" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="HighlightingSettingsPerFile">
|
||||
<setting file="file://$PROJECT_DIR$/src/Entity/BovinType.php" root0="FORCE_HIGHLIGHTING" root1="FORCE_HIGHLIGHTING" />
|
||||
</component>
|
||||
<component name="McpProjectServerCommands">
|
||||
<commands />
|
||||
<urls />
|
||||
@@ -62,7 +68,7 @@
|
||||
</server>
|
||||
</servers>
|
||||
</component>
|
||||
<component name="PhpWorkspaceProjectConfiguration" interpreter_name="C:/php-8.4.3/php.exe">
|
||||
<component name="PhpWorkspaceProjectConfiguration" interpreter_name="C:/php/php.exe">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
|
||||
@@ -225,37 +231,49 @@
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"git-widget-placeholder": "develop",
|
||||
"last_opened_file_path": "/home/sroy/Documents/test/Ferme",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "configurable.tailwindcss",
|
||||
"ts.external.directory.path": "/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
||||
"database.data.extractors.current.export.id": "Comma-separated (CSV)_id",
|
||||
"database.data.extractors.current.id": "Comma-separated (CSV)_id",
|
||||
"git-widget-placeholder": "feat/271-expedition-etape-1",
|
||||
"junie.onboarding.icon.badge.shown": "true",
|
||||
"last_opened_file_path": "//wsl.localhost/Ubuntu-24.04/home/matte/Ferme/frontend/services",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "preferences.keymap",
|
||||
"to.speed.mode.migration.done": "true",
|
||||
"ts.external.directory.path": "/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
},
|
||||
"keyToStringList": {
|
||||
"DatabaseDriversLRU": [
|
||||
"postgresql"
|
||||
"keyToStringList": {
|
||||
"DatabaseDriversLRU": [
|
||||
"postgresql"
|
||||
],
|
||||
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [
|
||||
"TEXT"
|
||||
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [
|
||||
"TEXT"
|
||||
],
|
||||
"vue.recent.templates": [
|
||||
"Vue Composition API Component"
|
||||
"vue.recent.templates": [
|
||||
"Vue Composition API Component"
|
||||
]
|
||||
}
|
||||
}</component>
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\matte\Ferme\frontend\services" />
|
||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\matte\Ferme\frontend\services\dto" />
|
||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\matte\Ferme\frontend\stores" />
|
||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\matte\Ferme\frontend\pages\shipment" />
|
||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\matte\Ferme\frontend\components\shipment" />
|
||||
</key>
|
||||
<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\tristan\workspace\ferme\templates" />
|
||||
@@ -297,10 +315,66 @@
|
||||
<workItem from="1770055690365" duration="370000" />
|
||||
<workItem from="1770056515646" duration="21000" />
|
||||
<workItem from="1770102495553" duration="2280000" />
|
||||
<workItem from="1770195604082" duration="90000" />
|
||||
<workItem from="1770195718952" duration="215000" />
|
||||
<workItem from="1770195959162" duration="18915000" />
|
||||
<workItem from="1770274844804" duration="3940000" />
|
||||
<workItem from="1770125858721" duration="10606000" />
|
||||
<workItem from="1770188542722" duration="1032000" />
|
||||
<workItem from="1770189650316" duration="5784000" />
|
||||
<workItem from="1770195538424" duration="16730000" />
|
||||
</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 id="LOCAL-00007" summary="test : ajout de TU sur les services et providers">
|
||||
<option name="closed" value="true" />
|
||||
<created>1768318921478</created>
|
||||
<option name="number" value="00007" />
|
||||
<option name="presentableId" value="LOCAL-00007" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1768318921478</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00008" summary="feat : ajout de la génération du bon de reception, correction de la base du formulaire multi-etape de reception et ajout d'une gestion d'erreur global">
|
||||
<option name="closed" value="true" />
|
||||
<created>1768498751836</created>
|
||||
<option name="number" value="00008" />
|
||||
<option name="presentableId" value="LOCAL-00008" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1768498751836</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00009" summary="feat : ajout d'une gestion d'erreur au global côté front avec la lib toaster et I18n pour centraliser les messages d'erreur">
|
||||
<option name="closed" value="true" />
|
||||
@@ -606,95 +680,39 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1769782099473</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00047" summary="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||
<task id="LOCAL-00047" summary="feat : mise à jour du bon de réception wip">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770131226364</created>
|
||||
<created>1770135384363</created>
|
||||
<option name="number" value="00047" />
|
||||
<option name="presentableId" value="LOCAL-00047" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770131226364</updated>
|
||||
<updated>1770135384363</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00048" summary="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||
<task id="LOCAL-00048" summary="feat : mise à jour du bon de réception WIP">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770206668867</created>
|
||||
<created>1770135408267</created>
|
||||
<option name="number" value="00048" />
|
||||
<option name="presentableId" value="LOCAL-00048" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770206668867</updated>
|
||||
<updated>1770135408267</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00049" summary="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||
<task id="LOCAL-00049" summary="feat : mise à jour du bon de réception WIP">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770217875423</created>
|
||||
<created>1770136359244</created>
|
||||
<option name="number" value="00049" />
|
||||
<option name="presentableId" value="LOCAL-00049" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770217875423</updated>
|
||||
<updated>1770136359244</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00050" summary="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||
<task id="LOCAL-00050" summary="feat : mise à jour du bon de réception WIP">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770283622425</created>
|
||||
<created>1770136475283</created>
|
||||
<option name="number" value="00050" />
|
||||
<option name="presentableId" value="LOCAL-00050" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770283622425</updated>
|
||||
<updated>1770136475283</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00051" summary="feat : ajout du responsive sur la navbar et la page d'accueil">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770308927948</created>
|
||||
<option name="number" value="00051" />
|
||||
<option name="presentableId" value="LOCAL-00051" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770308927948</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00052" summary="fix : logo centré en mod mobile">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770310504254</created>
|
||||
<option name="number" value="00052" />
|
||||
<option name="presentableId" value="LOCAL-00052" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770310504254</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00053" summary="feat : ajout d'un numéro de version automatique via la CI">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770369945257</created>
|
||||
<option name="number" value="00053" />
|
||||
<option name="presentableId" value="LOCAL-00053" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770369945257</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00054" summary="feat : update numéro de version">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770370216428</created>
|
||||
<option name="number" value="00054" />
|
||||
<option name="presentableId" value="LOCAL-00054" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770370216428</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00055" summary="fix : auto-tag-develop.yml">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770370700697</created>
|
||||
<option name="number" value="00055" />
|
||||
<option name="presentableId" value="LOCAL-00055" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770370700698</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00056" summary="fix : auto-tag-develop.yml">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770370919043</created>
|
||||
<option name="number" value="00056" />
|
||||
<option name="presentableId" value="LOCAL-00056" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770370919043</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00057" summary="feat : test auto-tag-develop.yml (auto incrément version)">
|
||||
<option name="closed" value="true" />
|
||||
<created>1770371073055</created>
|
||||
<option name="number" value="00057" />
|
||||
<option name="presentableId" value="LOCAL-00057" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1770371073055</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="58" />
|
||||
<option name="localTasksCounter" value="51" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
@@ -744,6 +762,11 @@
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<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 : 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" />
|
||||
@@ -762,14 +785,20 @@
|
||||
<MESSAGE value="feat : ajout de colonne pour les Supplier, Address et modification du numéro de réception" />
|
||||
<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 : Ajout de la sélection des bovins étape 3 d'une réception (WIP)" />
|
||||
<MESSAGE value="feat : ajout du responsive sur la navbar et la page d'accueil" />
|
||||
<MESSAGE value="fix : logo centré en mod mobile" />
|
||||
<MESSAGE value="feat : ajout d'un numéro de version automatique via la CI" />
|
||||
<MESSAGE value="feat : update numéro de version" />
|
||||
<MESSAGE value="fix : auto-tag-develop.yml" />
|
||||
<MESSAGE value="feat : test auto-tag-develop.yml (auto incrément version)" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="feat : test auto-tag-develop.yml (auto incrément version)" />
|
||||
<MESSAGE value="feat : mise à jour du bon de réception wip" />
|
||||
<MESSAGE value="feat : mise à jour du bon de réception WIP" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="feat : mise à jour du bon de réception WIP" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
<breakpoints>
|
||||
<line-breakpoint enabled="true" type="javascript">
|
||||
<url>file://$PROJECT_DIR$/frontend/stores/reception.ts</url>
|
||||
<properties lambdaOrdinal="-1" />
|
||||
<option name="timeStamp" value="2" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
<component name="XSLT-Support.FileAssociations.UIState">
|
||||
<expand />
|
||||
|
||||
@@ -27,8 +27,6 @@ Ajouter dans le fichier .env du frontend
|
||||
* Ajout du bundle malio/ednotif-bundle
|
||||
* Ajout de composant UI
|
||||
* Finalisation de la partie réception de marchandise
|
||||
* [#267] Lister les réceptions en attente
|
||||
* [#268] Lister les réceptions terminées
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@@ -53,8 +53,6 @@ security:
|
||||
- { path: ^/api/users, roles: PUBLIC_ACCESS, methods: [GET] }
|
||||
# Doc API (swagger) en public
|
||||
- { path: ^/api/docs, roles: PUBLIC_ACCESS }
|
||||
# Version de l'application en public
|
||||
- { path: ^/api/version, roles: PUBLIC_ACCESS, methods: [GET] }
|
||||
# Tout le reste nécessite un JWT
|
||||
- { path: ^/, roles: IS_AUTHENTICATED_FULLY }
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||
parameters:
|
||||
|
||||
imports:
|
||||
- { resource: version.yaml }
|
||||
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
_defaults:
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
parameters:
|
||||
app.version: '0.0.32'
|
||||
@@ -3,11 +3,3 @@
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { load } = useAppVersion()
|
||||
|
||||
onMounted(() => {
|
||||
load()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
|
||||
<template>
|
||||
<NuxtLink :to="link">
|
||||
<div class="w-[324px] h-[228px] border border-black rounded-md p-6 flex flex-col justify-between">
|
||||
<div class="flex justify-between">
|
||||
<div class="rounded-full w-[80px] h-[80px] bg-neutral-400 flex justify-center items-center">
|
||||
<Icon :name="iconName" style="color: black" size="44" />
|
||||
</div>
|
||||
<div>
|
||||
<Icon name="mdi:plus" style="color: black" size="44" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="uppercase font-bold">
|
||||
<p class="text-3xl"> {{ label }} </p>
|
||||
</div>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
link: string
|
||||
iconName: string
|
||||
label: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.BOVINS"
|
||||
class="flex flex-col items-center gap-16">
|
||||
<h1 class="text-4xl uppercase font-bold">Sélection des marchandises réceptionnnées</h1>
|
||||
<div
|
||||
class="flex flex-row gap-8 items-center">
|
||||
<div
|
||||
v-for="type in bovineType"
|
||||
:key="type.id"
|
||||
class="mt-8 flex flex-row mb-2 gap-6">
|
||||
<UiNumberInput
|
||||
:label="type.label"
|
||||
:code="type.code"
|
||||
v-model="bovineQuantities[String(type.id)]"
|
||||
:placeholder="0"
|
||||
:min="0"
|
||||
:max="10"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mt-8 flex flex-row mb-2 gap-6">
|
||||
<UiNumberInput
|
||||
label="Autres"
|
||||
v-model="otherQuantity"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
@click="goNext"
|
||||
>Peser
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||
import {getBovineTypeList} from "~/services/bovine-type";
|
||||
import {RECEPTION_TYPE_CODES} from "~/utils/constants";
|
||||
import {useReceptionStore} from '~/stores/reception'
|
||||
import {
|
||||
createReceptionBovine,
|
||||
deleteReceptionBovine,
|
||||
getReceptionBovineList,
|
||||
updateReceptionBovine
|
||||
} from "~/services/reception-bovine";
|
||||
import {computed, onMounted, reactive, ref, watch} from "vue";
|
||||
|
||||
const toast = useToast()
|
||||
const isLoadingBovineType = ref(false)
|
||||
const bovineType = ref<BovineTypeData[]>([])
|
||||
const receptionStore = useReceptionStore()
|
||||
const bovineQuantities = reactive<Record<string, number | null>>({})
|
||||
const otherQuantity = ref<number | null>(0)
|
||||
const receptionId = computed(() => receptionStore.current?.id ?? null)
|
||||
const receptionIri = computed(() =>
|
||||
receptionId.value ? `/api/receptions/${receptionId.value}` : null
|
||||
)
|
||||
const totalBovines = computed(() => {
|
||||
const base = Object.values(bovineQuantities).reduce((sum, value) => {
|
||||
return sum + (value ?? 0)
|
||||
}, 0)
|
||||
return base + (otherQuantity.value ?? 0)
|
||||
})
|
||||
|
||||
const loadBovineType = async () => {
|
||||
isLoadingBovineType.value = true
|
||||
try {
|
||||
bovineType.value = await getBovineTypeList()
|
||||
} finally {
|
||||
isLoadingBovineType.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadBovineType()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => receptionId.value,
|
||||
async (id) => {
|
||||
if (!id || !receptionIri.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const selectionMap: Record<string, number | null> = {}
|
||||
for (const type of bovineType.value) {
|
||||
selectionMap[String(type.id)] = 0
|
||||
}
|
||||
|
||||
const existing = await getReceptionBovineList(receptionIri.value)
|
||||
for (const selection of existing) {
|
||||
const bovineTypeId = String(selection.bovineType.id)
|
||||
selectionMap[bovineTypeId] = selection.quantity ?? 0
|
||||
}
|
||||
|
||||
for (const key of Object.keys(bovineQuantities)) {
|
||||
delete bovineQuantities[key]
|
||||
}
|
||||
Object.assign(bovineQuantities, selectionMap)
|
||||
|
||||
const existingOther = receptionStore.current?.bovineDetail
|
||||
const parsedOther =
|
||||
typeof existingOther === 'string' && existingOther.trim() !== ''
|
||||
? Number(existingOther)
|
||||
: 0
|
||||
otherQuantity.value = Number.isFinite(parsedOther) ? parsedOther : 0
|
||||
},
|
||||
{immediate: true}
|
||||
)
|
||||
|
||||
async function syncBovineSelections(receptionIri: string) {
|
||||
const existing = await getReceptionBovineList(receptionIri)
|
||||
const existingMap = new Map<string, { id: number; quantity: number | null }>()
|
||||
|
||||
for (const selection of existing) {
|
||||
const bovineTypeId = String(selection.bovineType.id)
|
||||
existingMap.set(bovineTypeId, {
|
||||
id: selection.id,
|
||||
quantity: selection.quantity ?? 0
|
||||
})
|
||||
}
|
||||
|
||||
// Supprime les entrées supprimées ou modifiées
|
||||
for (const [bovineTypeId, entry] of existingMap.entries()) {
|
||||
const selectedQuantity = bovineQuantities[bovineTypeId] ?? 0
|
||||
if (!selectedQuantity) {
|
||||
await deleteReceptionBovine(entry.id)
|
||||
existingMap.delete(bovineTypeId)
|
||||
continue
|
||||
}
|
||||
|
||||
if (selectedQuantity !== entry.quantity) {
|
||||
await updateReceptionBovine(entry.id, {quantity: selectedQuantity})
|
||||
existingMap.set(bovineTypeId, {
|
||||
id: entry.id,
|
||||
quantity: selectedQuantity
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Crée les entrées manquantes
|
||||
for (const [bovineTypeId, quantity] of Object.entries(bovineQuantities)) {
|
||||
if (!quantity) {
|
||||
continue
|
||||
}
|
||||
if (existingMap.has(bovineTypeId)) {
|
||||
// Déjà à jour
|
||||
continue
|
||||
}
|
||||
await createReceptionBovine({
|
||||
reception: receptionIri,
|
||||
bovineType: `/api/bovine_types/${bovineTypeId}`,
|
||||
quantity
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function goNext() {
|
||||
if (!receptionStore.current || !receptionIri.value) {
|
||||
return
|
||||
}
|
||||
|
||||
// @TODO Ajouter un composable pour le toaster qui gère les key i18n
|
||||
if (totalBovines.value > 52) {
|
||||
toast.error({
|
||||
title: 'Erreur',
|
||||
message: ('Le total des bovins ne peut pas dépasser 52.')
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const nextStep = receptionStore.current.currentStep + 1
|
||||
await syncBovineSelections(receptionIri.value)
|
||||
|
||||
await receptionStore.updateReception(receptionStore.current.id, {
|
||||
merchandiseType: null,
|
||||
merchandiseDetail: null,
|
||||
bovineDetail: otherQuantity.value ? String(otherQuantity.value) : null,
|
||||
currentStep: nextStep
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -142,8 +142,7 @@ import type {DriverData} from '~/services/dto/driver-data'
|
||||
import {getDriverList} from '~/services/driver'
|
||||
import type {VehicleData} from '~/services/dto/vehicle-data'
|
||||
import {getVehicleList} from '~/services/vehicle'
|
||||
import {RECEPTION_TYPE_CODES, SUPLLIER_CODE} from "~/utils/constants";
|
||||
import {deleteReceptionBovine, getReceptionBovineList} from "~/services/reception-bovine";
|
||||
import {SUPLLIER_CODE} from "~/utils/constants";
|
||||
|
||||
type ReceptionFormData = {
|
||||
licensePlate: string
|
||||
@@ -223,18 +222,6 @@ const filteredVehicles = computed<VehicleData[]>(() => {
|
||||
)
|
||||
})
|
||||
|
||||
const selectedReceptionType = computed(() =>
|
||||
receptionTypes.value.find((type) => String(type.id) === form.receptionTypeId) ?? null
|
||||
)
|
||||
|
||||
// Supprime les données bovines si on change de type de réception
|
||||
const clearReceptionBovines = async (receptionIri: string) => {
|
||||
const existing = await getReceptionBovineList(receptionIri)
|
||||
for (const selection of existing) {
|
||||
await deleteReceptionBovine(selection.id)
|
||||
}
|
||||
}
|
||||
|
||||
// Hydrate le formulaire depuis la réception en cours
|
||||
watch(
|
||||
() => receptionStore.current,
|
||||
@@ -522,16 +509,6 @@ async function validate() {
|
||||
return
|
||||
}
|
||||
|
||||
const previousTypeCode = receptionStore.current.receptionType?.code ?? null
|
||||
const nextTypeCode = selectedReceptionType.value?.code ?? null
|
||||
const receptionIri = `/api/receptions/${receptionStore.current.id}`
|
||||
|
||||
if (
|
||||
previousTypeCode === RECEPTION_TYPE_CODES.BOVINS &&
|
||||
nextTypeCode === RECEPTION_TYPE_CODES.MERCHANDISES
|
||||
) {
|
||||
await clearReceptionBovines(receptionIri)
|
||||
}
|
||||
const nextStep = receptionStore.current.currentStep + 1
|
||||
await receptionStore.updateReception(receptionStore.current.id, {
|
||||
currentStep: nextStep,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-16">
|
||||
<!-- @TODO voir pour séparer dans un composant au moment de l'implémentation des Bovins -->
|
||||
<div
|
||||
v-if="receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.MERCHANDISES"
|
||||
class="flex flex-col gap-16 items-center w-full">
|
||||
<h1 class="text-4xl uppercase font-bold">Sélection des marchandises réceptionnnées</h1>
|
||||
<h1 class="text-4xl uppercase font-bold">Sélectionner des marchandises réceptionnnées</h1>
|
||||
<UiSelect
|
||||
id="merchandise-type"
|
||||
v-model="selectedMerchandiseTypeId"
|
||||
@@ -11,6 +12,7 @@
|
||||
:options="merchandiseTypes.map((type) => ({ value: String(type.id), label: type.label }))"
|
||||
wrapper-class="w-[550px]"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-if="selectedMerchandiseTypeId && isAutres"
|
||||
class="flex flex-col w-full max-w-[550px]"
|
||||
@@ -67,27 +69,25 @@
|
||||
<button
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
@click="goNext"
|
||||
>Peser
|
||||
</button>
|
||||
>Peser</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, onMounted, ref} from 'vue'
|
||||
import {getBuildingList} from '~/services/building'
|
||||
import {getMerchandiseTypeList} from '~/services/merchandise-type'
|
||||
import type {MerchandiseTypeData} from '~/services/dto/merchandise-type-data'
|
||||
import type {BuildingData} from '~/services/dto/building-data'
|
||||
import type {PelletTypeData} from '~/services/dto/pellet-type-data'
|
||||
import {getPelletTypeList} from '~/services/pellet-type'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { getBuildingList } from '~/services/building'
|
||||
import { getMerchandiseTypeList } from '~/services/merchandise-type'
|
||||
import type { MerchandiseTypeData } from '~/services/dto/merchandise-type-data'
|
||||
import type { BuildingData } from '~/services/dto/building-data'
|
||||
import type { PelletTypeData } from '~/services/dto/pellet-type-data'
|
||||
import { getPelletTypeList } from '~/services/pellet-type'
|
||||
import {
|
||||
createReceptionPelletBuilding,
|
||||
deleteReceptionPelletBuilding,
|
||||
getReceptionPelletBuildingList
|
||||
} from '~/services/reception-pellet-building'
|
||||
import {useReceptionStore} from '~/stores/reception'
|
||||
import {MERCHANDISE_TYPE_CODES, RECEPTION_TYPE_CODES} from '~/utils/constants'
|
||||
import ReceptionBovineReceived from "~/components/reception/reception-bovine-received.vue";
|
||||
import { useReceptionStore } from '~/stores/reception'
|
||||
import { MERCHANDISE_TYPE_CODES, RECEPTION_TYPE_CODES } from '~/utils/constants'
|
||||
|
||||
const receptionStore = useReceptionStore()
|
||||
const merchandiseTypes = ref<MerchandiseTypeData[]>([])
|
||||
@@ -173,6 +173,7 @@ onMounted(async () => {
|
||||
}
|
||||
selectedPelletBuildingIds.value = selectionMap
|
||||
})
|
||||
|
||||
// Enregistre les sélections et passe à l'étape suivante
|
||||
async function goNext() {
|
||||
if (!receptionStore.current) {
|
||||
@@ -190,8 +191,6 @@ async function goNext() {
|
||||
buildings: isGranule.value
|
||||
? []
|
||||
: selectedBuildingIds.value.map((id) => `/api/buildings/${id}`),
|
||||
bovineDetail: null,
|
||||
bovinesTypes: null,
|
||||
currentStep: nextStep
|
||||
})
|
||||
|
||||
@@ -209,6 +208,7 @@ async function clearPelletSelections(receptionIri: string) {
|
||||
await deleteReceptionPelletBuilding(selection.id)
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronise les associations granulés/bâtiments avec l'état du formulaire
|
||||
async function syncPelletSelections(receptionIri: string) {
|
||||
const existing = await getReceptionPelletBuildingList(receptionIri)
|
||||
@@ -227,7 +227,7 @@ async function syncPelletSelections(receptionIri: string) {
|
||||
const desiredEntries: Array<{ pelletTypeId: string; buildingId: string }> = []
|
||||
for (const [pelletTypeId, buildingIds] of Object.entries(selectedPelletBuildingIds.value)) {
|
||||
for (const buildingId of buildingIds) {
|
||||
desiredEntries.push({pelletTypeId, buildingId})
|
||||
desiredEntries.push({ pelletTypeId, buildingId })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
<template>
|
||||
<div :class="['flex flex-row items-center gap-2', wrapperClass]">
|
||||
<label
|
||||
v-if="label"
|
||||
:for="id"
|
||||
class="text-xl text-bold flex items-center gap-2"
|
||||
:class="labelClass"
|
||||
>
|
||||
<span
|
||||
v-if="label">
|
||||
{{ label }}
|
||||
</span>
|
||||
<span
|
||||
v-if="code" class="text-neutral-600">
|
||||
({{ code }})
|
||||
</span>
|
||||
</label>
|
||||
<input
|
||||
:id="id"
|
||||
type="number"
|
||||
:value="modelValue ?? ''"
|
||||
:min="min"
|
||||
:max="max"
|
||||
:step="step"
|
||||
:disabled="disabled"
|
||||
v-bind="attrs"
|
||||
class="border-b border-black text-xl bg-transparent w-48"
|
||||
:class="[
|
||||
isEmpty ? 'text-neutral-400' : 'text-black',
|
||||
disabled ? 'cursor-not-allowed' : 'cursor-text',
|
||||
inputClass
|
||||
]"
|
||||
@keydown="onKeydown"
|
||||
@input="onInput"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, useAttrs} from 'vue'
|
||||
|
||||
defineOptions({inheritAttrs: false})
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
id?: string
|
||||
label?: string
|
||||
code?: string
|
||||
modelValue: number | string | null | undefined
|
||||
min?: number | string
|
||||
max?: number | string
|
||||
step?: number | string
|
||||
disabled?: boolean
|
||||
wrapperClass?: string
|
||||
labelClass?: string
|
||||
inputClass?: string
|
||||
}>(),
|
||||
{
|
||||
min: undefined,
|
||||
max: undefined,
|
||||
step: undefined,
|
||||
disabled: false,
|
||||
wrapperClass: '',
|
||||
labelClass: '',
|
||||
inputClass: ''
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'update:modelValue', value: number | null): void
|
||||
}>()
|
||||
|
||||
const attrs = useAttrs()
|
||||
const isEmpty = computed(() => props.modelValue === null || props.modelValue === undefined || props.modelValue === '')
|
||||
|
||||
const onInput = (event: Event) => {
|
||||
const target = event.target as HTMLInputElement
|
||||
if (target.value === '') {
|
||||
emit('update:modelValue', null)
|
||||
return
|
||||
}
|
||||
const numeric = Math.max(0, Number(target.value))
|
||||
emit('update:modelValue', Number.isNaN(numeric) ? null : numeric)
|
||||
}
|
||||
|
||||
const onKeydown = (event: KeyboardEvent) => {
|
||||
if (event.key === '-' || event.key === 'e' || event.key === 'E') {
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
export const useAppVersion = () => {
|
||||
const api = useApi()
|
||||
const version = useState<string | null>('app-version', () => null)
|
||||
|
||||
const load = async () => {
|
||||
if (version.value) {
|
||||
return version.value
|
||||
}
|
||||
const response = await api.get<{ version: string }>('version', {}, {
|
||||
toast: false
|
||||
})
|
||||
version.value = response.version
|
||||
return version.value
|
||||
}
|
||||
|
||||
return { version, load }
|
||||
}
|
||||
@@ -1,72 +1,64 @@
|
||||
{
|
||||
"errors": {
|
||||
"http": {
|
||||
"get": "Impossible de récupérer les données.",
|
||||
"post": "Impossible de créer la ressource.",
|
||||
"put": "Impossible de mettre à jour la ressource.",
|
||||
"patch": "Impossible de mettre à jour la ressource.",
|
||||
"delete": "Impossible de supprimer la ressource."
|
||||
},
|
||||
"reception": {
|
||||
"list": "Impossible de récupérer la liste des réceptions.",
|
||||
"fetch": "Impossible de récupérer la réception.",
|
||||
"create": "Impossible de créer la réception.",
|
||||
"update": "Impossible de mettre à jour la réception.",
|
||||
"weigh": "Impossible de récupérer la pesée."
|
||||
},
|
||||
"receptionType": {
|
||||
"list": "Impossible de récupérer la liste des types de réception."
|
||||
},
|
||||
"merchandiseType": {
|
||||
"list": "Impossible de récupérer la liste des types de marchandises."
|
||||
},
|
||||
"building": {
|
||||
"list": "Impossible de récupérer la liste des bâtiments."
|
||||
},
|
||||
"pelletType": {
|
||||
"list": "Impossible de récupérer la liste des types de granulés."
|
||||
},
|
||||
"receptionPelletBuilding": {
|
||||
"list": "Impossible de récupérer la liste des dépôts de granulés.",
|
||||
"create": "Impossible d'enregistrer le dépôt de granulés.",
|
||||
"delete": "Impossible de supprimer le dépôt de granulés."
|
||||
},
|
||||
"receptionBovine": {
|
||||
"list": "Impossible de récupérer la liste des bovins de la réception.",
|
||||
"create": "Impossible d'enregistrer le bovin.",
|
||||
"delete": "Impossible de supprimer le bovin."
|
||||
},
|
||||
"supplier": {
|
||||
"list": "Impossible de récupérer la liste des fournisseurs."
|
||||
},
|
||||
"truck": {
|
||||
"list": "Impossible de récupérer la liste des camions."
|
||||
},
|
||||
"bovin": {
|
||||
"list": "Impossible de récupérer la liste des races de bovins."
|
||||
},
|
||||
"carrier": {
|
||||
"list": "Impossible de récupérer la liste des transporteurs."
|
||||
},
|
||||
"driver": {
|
||||
"list": "Impossible de récupérer la liste des chauffeurs."
|
||||
},
|
||||
"vehicle": {
|
||||
"list": "Impossible de récupérer la liste des immatriculations."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Identifiants invalides.",
|
||||
"users": "Impossible de récupérer les utilisateurs.",
|
||||
"logout": "Impossible de se déconnecter."
|
||||
}
|
||||
"errors": {
|
||||
"http": {
|
||||
"get": "Impossible de récupérer les données.",
|
||||
"post": "Impossible de créer la ressource.",
|
||||
"put": "Impossible de mettre à jour la ressource.",
|
||||
"patch": "Impossible de mettre à jour la ressource.",
|
||||
"delete": "Impossible de supprimer la ressource."
|
||||
},
|
||||
"success": {
|
||||
"reception": {
|
||||
"update": "Réception mise à jour avec succès."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Connexion réussie.",
|
||||
"logout": "Déconnexion réussie."
|
||||
}
|
||||
"reception": {
|
||||
"list": "Impossible de récupérer la liste des réceptions.",
|
||||
"fetch": "Impossible de récupérer la réception.",
|
||||
"create": "Impossible de créer la réception.",
|
||||
"update": "Impossible de mettre à jour la réception.",
|
||||
"weigh": "Impossible de récupérer la pesée."
|
||||
},
|
||||
"receptionType": {
|
||||
"list": "Impossible de récupérer la liste des types de réception."
|
||||
},
|
||||
"merchandiseType": {
|
||||
"list": "Impossible de récupérer la liste des types de marchandises."
|
||||
},
|
||||
"building": {
|
||||
"list": "Impossible de récupérer la liste des bâtiments."
|
||||
},
|
||||
"pelletType": {
|
||||
"list": "Impossible de récupérer la liste des types de granulés."
|
||||
},
|
||||
"receptionPelletBuilding": {
|
||||
"list": "Impossible de récupérer la liste des dépôts de granulés.",
|
||||
"create": "Impossible d'enregistrer le dépôt de granulés.",
|
||||
"delete": "Impossible de supprimer le dépôt de granulés."
|
||||
},
|
||||
"supplier": {
|
||||
"list": "Impossible de récupérer la liste des fournisseurs."
|
||||
},
|
||||
"truck": {
|
||||
"list": "Impossible de récupérer la liste des camions."
|
||||
},
|
||||
"carrier": {
|
||||
"list": "Impossible de récupérer la liste des transporteurs."
|
||||
},
|
||||
"driver": {
|
||||
"list": "Impossible de récupérer la liste des chauffeurs."
|
||||
},
|
||||
"vehicle": {
|
||||
"list": "Impossible de récupérer la liste des immatriculations."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Identifiants invalides.",
|
||||
"users": "Impossible de récupérer les utilisateurs.",
|
||||
"logout": "Impossible de se déconnecter."
|
||||
}
|
||||
},
|
||||
"success": {
|
||||
"reception": {
|
||||
"update": "Réception mise à jour avec succès."
|
||||
},
|
||||
"auth": {
|
||||
"login": "Connexion réussie.",
|
||||
"logout": "Déconnexion réussie."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div class="min-h-screen text-neutral-900 grid grid-rows-[85px,1fr]">
|
||||
<!-- HEADER -->
|
||||
<header class="bg-primary-500 z-50 h-[85px]">
|
||||
<div class="h-full w-full px-6 grid grid-cols-[auto,1fr,auto] items-center gap-8">
|
||||
<NuxtLink to="/" class="grid place-items-center">
|
||||
<span class="grid place-items-center bg-white text-xl font-bold uppercase text-primary-500 p-4">
|
||||
LOGO
|
||||
</span>
|
||||
</NuxtLink>
|
||||
|
||||
<nav class="text-2xl font-bold uppercase text-white"></nav>
|
||||
|
||||
<NuxtLink
|
||||
to="/"
|
||||
class="text-xl font-bold uppercase text-white transition hover:opacity-80 justify-self-end"
|
||||
>
|
||||
Quitter le panel admin
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="grid grid-cols-[16rem,1fr] h-[calc(100vh-85px)] min-h-0">
|
||||
<aside class="bg-primary-500 text-white min-h-0 grid grid-rows-[auto,1fr,auto]">
|
||||
<div class="p-4 font-semibold">Tableau de bord</div>
|
||||
|
||||
<div class="overflow-y-auto min-h-0 p-4 space-y-3">
|
||||
<!-- Liste des liens à ajouter ci-dessous -->
|
||||
|
||||
</div>
|
||||
|
||||
<div class="p-4">
|
||||
<button
|
||||
@click="handleLogout"
|
||||
class="w-full bg-red-600 hover:bg-red-700 py-2 rounded font-bold"
|
||||
>
|
||||
Déconnexion
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="min-h-0 overflow-auto px-12 py-12 ">
|
||||
<div class="w-full ">
|
||||
<slot />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await auth.logout()
|
||||
} finally {
|
||||
await navigateTo('/login')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,16 +1,15 @@
|
||||
<template>
|
||||
<div class="min-h-screen bg-white text-neutral-900">
|
||||
<header class="w-full border-b border-neutral-200 bg-primary-500">
|
||||
<div class="flex w-full items-center justify-center px-6 py-4">
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center justify-center text-3xl text-white md:hidden"
|
||||
aria-label="Ouvrir le menu"
|
||||
@click="toggleMenu"
|
||||
>
|
||||
<span aria-hidden="true" class="flex items-center"><Icon name="mdi:menu" size="44"/></span>
|
||||
</button>
|
||||
<nav class="ml-4 hidden items-center gap-8 text-2xl font-bold uppercase text-white md:flex">
|
||||
<div class="flex w-full items-center px-6 py-4">
|
||||
<NuxtLink to="/" class="flex items-center gap-3">
|
||||
<span
|
||||
class="flex items-center justify-center bg-white text-xl font-bold uppercase text-primary-500 p-4"
|
||||
>
|
||||
LOGO
|
||||
</span>
|
||||
</NuxtLink>
|
||||
<nav class="mx-8 flex flex-1 gap-8 text-2xl font-bold uppercase text-white">
|
||||
<NuxtLink to="/" custom v-slot="{ href, navigate, isExactActive }">
|
||||
<a
|
||||
:href="href"
|
||||
@@ -20,89 +19,28 @@
|
||||
Accueil
|
||||
</a>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/admin/dashboard" custom v-slot="{ href, navigate, isActive }">
|
||||
<NuxtLink to="/reception" custom v-slot="{ href, navigate, isActive }">
|
||||
<a
|
||||
:href="href"
|
||||
@click="navigate"
|
||||
:class="isReceptionActive ? 'opacity-100' : 'opacity-50'"
|
||||
>
|
||||
Admin
|
||||
Reception
|
||||
</a>
|
||||
</NuxtLink>
|
||||
</nav>
|
||||
<NuxtLink to="/" class="flex flex-1 items-center justify-center gap-3">
|
||||
<span
|
||||
class="flex items-center justify-center bg-white text-xl font-bold uppercase text-primary-500 p-4"
|
||||
>
|
||||
LOGO
|
||||
</span>
|
||||
</NuxtLink>
|
||||
<div class="w-[44px] md:hidden"></div>
|
||||
<button
|
||||
type="button"
|
||||
class="ml-auto hidden text-xl font-bold uppercase text-white transition hover:opacity-80 md:inline-flex"
|
||||
class="ml-auto text-xl font-bold uppercase text-white transition hover:opacity-80"
|
||||
@click="handleLogout"
|
||||
>
|
||||
Déconnexion
|
||||
</button>
|
||||
</div>
|
||||
<transition
|
||||
enter-active-class="transition duration-200 ease-out"
|
||||
enter-from-class="opacity-0"
|
||||
enter-to-class="opacity-100"
|
||||
leave-active-class="transition duration-150 ease-in"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0"
|
||||
>
|
||||
<div
|
||||
v-if="isMenuOpen"
|
||||
class="fixed inset-0 z-40 bg-black/40 md:hidden"
|
||||
@click="closeMenu"
|
||||
/>
|
||||
</transition>
|
||||
<transition
|
||||
enter-active-class="transition duration-200 ease-out"
|
||||
enter-from-class="-translate-x-full"
|
||||
enter-to-class="translate-x-0"
|
||||
leave-active-class="transition duration-150 ease-in"
|
||||
leave-from-class="translate-x-0"
|
||||
leave-to-class="-translate-x-full"
|
||||
>
|
||||
<aside
|
||||
v-if="isMenuOpen"
|
||||
class="fixed left-0 top-0 z-50 h-full w-full bg-primary-600 px-6 pb-8 pt-6 text-white shadow-xl md:hidden"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-2xl font-bold uppercase">Menu</span>
|
||||
<button
|
||||
type="button"
|
||||
class="text-2xl"
|
||||
aria-label="Fermer le menu"
|
||||
@click="closeMenu"
|
||||
>
|
||||
<Icon name="mdi:close" size="44"/>
|
||||
</button>
|
||||
</div>
|
||||
<nav class="mt-8 flex flex-col gap-6 text-xl font-bold uppercase">
|
||||
<NuxtLink to="/" class="opacity-100" @click="closeMenu">Accueil</NuxtLink>
|
||||
</nav>
|
||||
<button
|
||||
type="button"
|
||||
class="mt-5 text-xl font-bold uppercase"
|
||||
@click="handleLogout"
|
||||
>
|
||||
Déconnexion
|
||||
</button>
|
||||
</aside>
|
||||
</transition>
|
||||
</header>
|
||||
<main class="mx-auto w-full max-w-[1280px] pb-0">
|
||||
<main class="mx-auto w-full max-w-[1280px] px-6 pt-[85px] pb-0">
|
||||
<slot/>
|
||||
</main>
|
||||
<footer class="w-full mt-8 bg-primary-500 p-6">
|
||||
<p class="font-bold text-white text-right">v{{ version }}</p>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -111,22 +49,12 @@ import { useAuthStore } from '~/stores/auth'
|
||||
|
||||
const route = useRoute()
|
||||
const auth = useAuthStore()
|
||||
const isMenuOpen = ref(false)
|
||||
const { version } = useAppVersion()
|
||||
|
||||
const closeMenu = () => {
|
||||
isMenuOpen.value = false
|
||||
}
|
||||
|
||||
const toggleMenu = () => {
|
||||
isMenuOpen.value = !isMenuOpen.value
|
||||
}
|
||||
const isReceptionActive = computed(() => route.path.startsWith('/reception'))
|
||||
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
await auth.logout()
|
||||
} finally {
|
||||
closeMenu()
|
||||
await navigateTo('/login')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@ export default defineNuxtConfig({
|
||||
'@nuxtjs/tailwindcss',
|
||||
'@pinia/nuxt',
|
||||
'nuxt-toast',
|
||||
'@nuxtjs/i18n',
|
||||
'@nuxt/icon'
|
||||
'@nuxtjs/i18n'
|
||||
],
|
||||
css: ['~/assets/css/main.css', '~/assets/css/toast.css'],
|
||||
runtimeConfig: {
|
||||
|
||||
77
frontend/package-lock.json
generated
77
frontend/package-lock.json
generated
@@ -7,7 +7,6 @@
|
||||
"name": "frontend",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@nuxt/icon": "^2.2.1",
|
||||
"@nuxtjs/i18n": "^10.2.1",
|
||||
"@pinia/nuxt": "^0.11.3",
|
||||
"izitoast": "^1.4.0",
|
||||
@@ -36,19 +35,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/install-pkg": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz",
|
||||
"integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"package-manager-detector": "^1.3.0",
|
||||
"tinyexec": "^1.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
@@ -1262,47 +1248,6 @@
|
||||
"url": "https://github.com/sponsors/nzakas"
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify/collections": {
|
||||
"version": "1.0.646",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/collections/-/collections-1.0.646.tgz",
|
||||
"integrity": "sha512-zA5Gr1MJm1SI0TjOUl7wu4kvBWXQ6Uh8ALEtqQ5ucXyUxP2M8m2bk2hfVtGykSdMlDB+Xs2AHbJ9pQqayz9WGQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iconify/types": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify/types": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
|
||||
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@iconify/utils": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz",
|
||||
"integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@antfu/install-pkg": "^1.1.0",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"mlly": "^1.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify/vue": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/vue/-/vue-5.0.0.tgz",
|
||||
"integrity": "sha512-C+KuEWIF5nSBrobFJhT//JS87OZ++QDORB6f2q2Wm6fl2mueSTpFBeBsveK0KW9hWiZ4mNiPjsh6Zs4jjdROSg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iconify/types": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/cyberalien"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/bundle-utils": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-11.0.3.tgz",
|
||||
@@ -2323,28 +2268,6 @@
|
||||
"devtools-wizard": "cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@nuxt/icon": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/icon/-/icon-2.2.1.tgz",
|
||||
"integrity": "sha512-GI840yYGuvHI0BGDQ63d6rAxGzG96jQcWrnaWIQKlyQo/7sx9PjXkSHckXUXyX1MCr9zY6U25Td6OatfY6Hklw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iconify/collections": "^1.0.641",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"@iconify/utils": "^3.1.0",
|
||||
"@iconify/vue": "^5.0.0",
|
||||
"@nuxt/devtools-kit": "^3.1.1",
|
||||
"@nuxt/kit": "^4.2.2",
|
||||
"consola": "^3.4.2",
|
||||
"local-pkg": "^1.1.2",
|
||||
"mlly": "^1.8.0",
|
||||
"ohash": "^2.0.11",
|
||||
"pathe": "^2.0.3",
|
||||
"picomatch": "^4.0.3",
|
||||
"std-env": "^3.10.0",
|
||||
"tinyglobby": "^0.2.15"
|
||||
}
|
||||
},
|
||||
"node_modules/@nuxt/kit": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.2.2.tgz",
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"build:dist": "nuxt generate && rm -rf dist && cp -R .output/public dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/icon": "^2.2.1",
|
||||
"@nuxtjs/i18n": "^10.2.1",
|
||||
"@pinia/nuxt": "^0.11.3",
|
||||
"izitoast": "^1.4.0",
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
layout: 'admin'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>test</h1>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,15 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex flex-wrap justify-center mt-8 gap-8 mb-8 md:mb-0">
|
||||
<card-link label="NOUVELLE RÉCEPTION" link="/reception" iconName="mdi:truck-outline" />
|
||||
<card-link label="NOUVELLE EXPÉDITION" link="/" iconName="mdi:truck-fast-outline" />
|
||||
<card-link label="PLAN DE SITE" link="/" iconName="mdi:warehouse" />
|
||||
<card-link label="RÉCEPTIONS EN ATTENTE" link="/reception/waiting-reception" iconName="mdi:truck-remove-outline" />
|
||||
<card-link label="EXPÉDITIONS EN ATTENTE" link="/" iconName="mdi:truck-cargo-container" />
|
||||
<card-link label="CASES" link="/" iconName="mdi:cube-outline" />
|
||||
<card-link label="RÉCEPTIONS FINIES" link="/reception/finish-reception" iconName="mdi:truck-check-outline" />
|
||||
<card-link label="EXPÉDITIONS FINIES" link="/" iconName="mdi:truck-delivery-outline" />
|
||||
<card-link label="PASSEPORT DU BOVIN" link="/" iconName="mdi:cow" />
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold">Liste des receptions</h1>
|
||||
<div class="mt-6 border border-slate-200">
|
||||
<div class="grid grid-cols-6 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide">
|
||||
<div>ID</div>
|
||||
<div>Immatriculation</div>
|
||||
<div>Pesée plein</div>
|
||||
<div>Pesée vide</div>
|
||||
<div>Etape</div>
|
||||
<div>Date</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="reception in receptionList"
|
||||
:key="reception.id"
|
||||
class="grid grid-cols-6 gap-4 px-4 py-3 text-sm hover:bg-slate-50 cursor-pointer border-t border-slate-200"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="goToReception(reception.id)"
|
||||
@keydown.enter="goToReception(reception.id)"
|
||||
>
|
||||
<div>{{ reception.id }}</div>
|
||||
<div>{{ reception.licensePlate }}</div>
|
||||
<div>{{ formatWeighing(reception, 'gross') }}</div>
|
||||
<div>{{ formatWeighing(reception, 'tare') }}</div>
|
||||
<div>{{ reception.currentStep }}</div>
|
||||
<div>{{ reception.receptionDate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {ReceptionData} from "~/services/dto/reception-data";
|
||||
import {getReceptionList} from "~/services/reception";
|
||||
|
||||
const receptionList = ref<ReceptionData[]>()
|
||||
const router = useRouter()
|
||||
|
||||
const goToReception = (id: number) => {
|
||||
router.push(`/reception/${id}`)
|
||||
}
|
||||
|
||||
const formatWeighing = (reception: ReceptionData, type: 'gross' | 'tare') => {
|
||||
const entry = reception.weights?.find((weight) => weight.type === type)
|
||||
if (!entry || entry.weight == null || entry.dsd == null) {
|
||||
return '—'
|
||||
}
|
||||
return `${entry.weight} kg / ${entry.dsd} dsd`
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
receptionList.value = await getReceptionList()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -46,8 +46,7 @@
|
||||
>
|
||||
Connexion
|
||||
</button>
|
||||
<p class="font-bold">v{{ version }}</p>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -58,7 +57,6 @@ import { useAuthStore } from '~/stores/auth'
|
||||
|
||||
const router = useRouter()
|
||||
const auth = useAuthStore()
|
||||
const { version } = useAppVersion()
|
||||
|
||||
definePageMeta({
|
||||
layout: 'auth'
|
||||
|
||||
@@ -16,12 +16,7 @@
|
||||
</div>
|
||||
<ReceptionForm v-if="!storeReception || storeReception.currentStep === 0"/>
|
||||
<ReceptionWeight v-if="storeReception?.currentStep === 1" mode="gross"/>
|
||||
<ReceptionProductReceived
|
||||
v-if="storeReception?.currentStep === 2 &&
|
||||
receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.MERCHANDISES"/>
|
||||
<ReceptionBovineReceived
|
||||
v-if="storeReception?.currentStep === 2 &&
|
||||
receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.BOVINS"/>
|
||||
<ReceptionProductReceived v-if="storeReception?.currentStep === 2"/>
|
||||
<ReceptionWeight v-if="storeReception?.currentStep !== null && storeReception?.currentStep >= 3" mode="tare"/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,7 +25,6 @@
|
||||
import {useReceptionStore} from '~/stores/reception'
|
||||
import {storeToRefs} from 'pinia'
|
||||
import {RECEPTION_STEP_LABELS} from '~/constants/steps'
|
||||
import {RECEPTION_TYPE_CODES} from "~/utils/constants";
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-start gap-10">
|
||||
<Icon @click="router.push('/')" name="gg:arrow-left-o" style="color: black" size="44" />
|
||||
<h1 class="text-3xl font-bold uppercase">listes des réceptions finie</h1>
|
||||
</div>
|
||||
|
||||
<div class="ps-20 " >
|
||||
<div class="mt-6 border border-slate-200 mb-16 ">
|
||||
<div class="grid grid-cols-6 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide">
|
||||
<div>Numéro</div>
|
||||
<div>Date</div>
|
||||
<div>Fournisseur</div>
|
||||
<div>Adresse</div>
|
||||
<div>Type réception</div>
|
||||
<div>Poids</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="reception in receptionList"
|
||||
:key="reception.id"
|
||||
class="grid grid-cols-6 gap-4 px-4 py-3 text-sm hover:bg-slate-50 cursor-pointer border-t border-slate-200"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div>{{ reception.identificationNumber}}</div>
|
||||
<div>{{ reception.receptionDate}}</div>
|
||||
<div>{{ reception.supplier?.name }}</div>
|
||||
<div>{{ reception.address?.fullAddress }}</div>
|
||||
<div>{{ reception.receptionType?.label }}</div>
|
||||
<div>{{ formatWeighing(reception, 'gross') }} | {{ formatWeighing(reception, 'tare') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {ReceptionData} from "~/services/dto/reception-data";
|
||||
import {getReceptionList} from "~/services/reception";
|
||||
|
||||
const receptionList = ref<ReceptionData[]>()
|
||||
const router = useRouter()
|
||||
|
||||
const formatWeighing = (reception: ReceptionData, type: 'gross' | 'tare') => {
|
||||
const entry = reception.weights?.find((weight) => weight.type === type)
|
||||
if (!entry || entry.weight == null || entry.dsd == null) {
|
||||
return '—'
|
||||
}
|
||||
return `${entry.weight} kg`
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
receptionList.value = await getReceptionList(true)
|
||||
})
|
||||
</script>
|
||||
@@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-between ">
|
||||
<div class="flex items-center gap-10">
|
||||
<Icon @click="router.push('/')" name="gg:arrow-left-o" style="color: black" size="44" />
|
||||
<h1 class="text-3xl font-bold uppercase">listes des réceptions en attente</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ps-20 " >
|
||||
<div class="mt-6 border border-slate-200 mb-16 ">
|
||||
<div class="grid grid-cols-5 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide">
|
||||
<div>Fournisseur</div>
|
||||
<div>Adresse</div>
|
||||
<div>Type réception</div>
|
||||
<div>Transporteur</div>
|
||||
<div>Immatriculation</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="reception in receptionList"
|
||||
:key="reception.id"
|
||||
class="grid grid-cols-5 gap-4 px-4 py-3 text-sm hover:bg-slate-50 cursor-pointer border-t border-slate-200"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="goToReception(reception.id)"
|
||||
@keydown.enter="goToReception(reception.id)"
|
||||
>
|
||||
<div>{{ reception.supplier?.name }}</div>
|
||||
<div>{{ reception.address?.fullAddress }}</div>
|
||||
<div>{{ reception.receptionType?.label }}</div>
|
||||
<div>{{ reception.carrier?.name }}</div>
|
||||
<div>{{ reception.licensePlate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {ReceptionData} from "~/services/dto/reception-data";
|
||||
import {getReceptionList} from "~/services/reception";
|
||||
|
||||
const receptionList = ref<ReceptionData[]>()
|
||||
const router = useRouter()
|
||||
|
||||
const goToReception = (id: number) => {
|
||||
router.push(`/reception/${id}`)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
receptionList.value = await getReceptionList(false)
|
||||
})
|
||||
</script>
|
||||
@@ -1,23 +0,0 @@
|
||||
import { useApi } from '~/composables/useApi'
|
||||
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||
|
||||
export type BovineTypeListResponse =
|
||||
| BovineTypeData[]
|
||||
| { 'hydra:member'?: BovineTypeData[] }
|
||||
|
||||
export async function getBovineTypeList(): Promise<BovineTypeData[]> {
|
||||
const api = useApi()
|
||||
const response = await api.get<BovineTypeListResponse>('bovine_types', {}, {
|
||||
toastErrorKey: 'errors.bovin.list'
|
||||
})
|
||||
|
||||
if (Array.isArray(response)) {
|
||||
return response
|
||||
}
|
||||
|
||||
if (response && typeof response === 'object' && Array.isArray(response['hydra:member'])) {
|
||||
return response['hydra:member']
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
export interface BovineTypeData{
|
||||
id: number
|
||||
label: string
|
||||
code: string
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||
|
||||
export interface ReceptionBovineTypeData{
|
||||
id: number
|
||||
quantity : number
|
||||
reception?: string
|
||||
bovineType: BovineTypeData
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import type { AddressData } from '~/services/dto/address-data'
|
||||
import type { TruckData } from '~/services/dto/truck-data'
|
||||
import type { CarrierData } from '~/services/dto/carrier-data'
|
||||
import type { DriverData } from '~/services/dto/driver-data'
|
||||
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||
|
||||
export interface ReceptionData {
|
||||
id: number
|
||||
@@ -21,9 +20,7 @@ export interface ReceptionData {
|
||||
receptionType?: ReceptionTypeData | null
|
||||
merchandiseType?: MerchandiseTypeData | null
|
||||
merchandiseDetail?: string | null
|
||||
bovineDetail?: string | null
|
||||
buildings?: BuildingData[] | null
|
||||
bovinesTypes?: BovineTypeData[] | null
|
||||
pelletBuildings?: ReceptionPelletBuildingData[] | null
|
||||
user?: UserData | null
|
||||
supplier?: SupplierData | null
|
||||
@@ -49,9 +46,7 @@ export type ReceptionPayload = {
|
||||
receptionType?: string | null
|
||||
merchandiseType?: string | null
|
||||
merchandiseDetail?: string | null
|
||||
bovineDetail?: string | null
|
||||
buildings?: string[] | null
|
||||
bovinesTypes?: string[] | null
|
||||
user?: string | null
|
||||
supplier?: string | null
|
||||
address?: string | null
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { useApi } from '~/composables/useApi'
|
||||
import type { ReceptionBovineTypeData } from '~/services/dto/reception-bovine-data'
|
||||
|
||||
export type ReceptionBovineListResponse =
|
||||
| ReceptionBovineTypeData[]
|
||||
| { 'hydra:member'?: ReceptionBovineTypeData[] }
|
||||
|
||||
export type ReceptionBovinePayload = {
|
||||
quantity: number
|
||||
reception: string
|
||||
bovineType: string
|
||||
}
|
||||
|
||||
export async function getReceptionBovineList(
|
||||
receptionIri: string
|
||||
): Promise<ReceptionBovineTypeData[]> {
|
||||
const api = useApi()
|
||||
const response = await api.get<ReceptionBovineListResponse>(
|
||||
'reception_bovines',
|
||||
{ reception: receptionIri },
|
||||
{
|
||||
toastErrorKey: 'errors.receptionBovine.list'
|
||||
}
|
||||
)
|
||||
|
||||
if (Array.isArray(response)) {
|
||||
return response
|
||||
}
|
||||
if (response && typeof response === 'object' && Array.isArray(response['hydra:member'])) {
|
||||
return response['hydra:member']
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
export async function createReceptionBovine(
|
||||
payload: ReceptionBovinePayload
|
||||
): Promise<ReceptionBovineTypeData> {
|
||||
const api = useApi()
|
||||
return api.post<ReceptionBovineTypeData>('reception_bovines', payload, {
|
||||
toastErrorKey: 'errors.receptionBovine.create'
|
||||
})
|
||||
}
|
||||
|
||||
export async function deleteReceptionBovine(id: number): Promise<void> {
|
||||
const api = useApi()
|
||||
await api.delete<void>(`reception_bovines/${id}`, {}, {
|
||||
toastErrorKey: 'errors.receptionBovine.delete'
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateReceptionBovine(
|
||||
id: number,
|
||||
payload: Partial<ReceptionBovinePayload>
|
||||
): Promise<ReceptionBovineTypeData> {
|
||||
const api = useApi()
|
||||
return api.patch<ReceptionBovineTypeData>(`reception_bovines/${id}`, payload, {
|
||||
toastErrorKey: 'errors.receptionBovine.update'
|
||||
})
|
||||
}
|
||||
@@ -2,15 +2,13 @@ import {useApi} from '~/composables/useApi'
|
||||
import type {ReceptionData, ReceptionPayload} from '~/services/dto/reception-data'
|
||||
import type {WeightData} from '~/services/dto/weight-data'
|
||||
|
||||
export async function getReceptionList(isValid: boolean|null = null) {
|
||||
export async function getReceptionList() {
|
||||
const api = useApi()
|
||||
const query = isValid !== null ? { isValid: isValid} : {}
|
||||
return api.get<ReceptionData[]>('receptions', query, {
|
||||
return api.get<ReceptionData>(`receptions`, {}, {
|
||||
toastErrorKey: 'errors.reception.list'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export async function getReception(id: number) {
|
||||
const api = useApi()
|
||||
return api.get<ReceptionData>(`receptions/${id}`, {}, {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export const RECEPTION_TYPE_CODES = {
|
||||
MERCHANDISES: 'MARCHANDISES',
|
||||
BOVINS: 'BOVINS'
|
||||
MERCHANDISES: 'MARCHANDISES'
|
||||
} as const
|
||||
|
||||
export const MERCHANDISE_TYPE_CODES = {
|
||||
|
||||
2
makefile
2
makefile
@@ -79,7 +79,7 @@ migration-migrate:
|
||||
$(SYMFONY_CONSOLE) --no-interaction doctrine:migrations:migrate --allow-no-migration
|
||||
|
||||
fixtures:
|
||||
$(SYMFONY_CONSOLE) doctrine:fixtures:load
|
||||
$(SYMFONY_CONSOLE) --no-interaction doctrine:fixtures:load
|
||||
|
||||
# Attention, supprime votre bdd local
|
||||
db-reset:
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260203123833 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE TABLE bovine_type (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(120) NOT NULL, code VARCHAR(50) NOT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE TABLE reception_bovine (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, quantity INT NOT NULL, reception_id INT DEFAULT NULL, bovine_type_id INT NOT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE INDEX IDX_636B9DB97C14DF52 ON reception_bovine (reception_id)');
|
||||
$this->addSql('CREATE INDEX IDX_636B9DB97899F32E ON reception_bovine (bovine_type_id)');
|
||||
$this->addSql('ALTER TABLE reception_bovine ADD CONSTRAINT FK_636B9DB97C14DF52 FOREIGN KEY (reception_id) REFERENCES reception (id)');
|
||||
$this->addSql('ALTER TABLE reception_bovine ADD CONSTRAINT FK_636B9DB97899F32E FOREIGN KEY (bovine_type_id) REFERENCES bovine_type (id) NOT DEFERRABLE');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE reception_bovine DROP CONSTRAINT FK_636B9DB97C14DF52');
|
||||
$this->addSql('ALTER TABLE reception_bovine DROP CONSTRAINT FK_636B9DB97899F32E');
|
||||
$this->addSql('DROP TABLE bovine_type');
|
||||
$this->addSql('DROP TABLE reception_bovine');
|
||||
}
|
||||
}
|
||||
64
migrations/Version20260204101625.php
Normal file
64
migrations/Version20260204101625.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260204101625 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE TABLE bovin_shipment (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, nb_bovin_send INT NOT NULL, shipment_id INT DEFAULT NULL, shipment_type_id INT DEFAULT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE INDEX IDX_7049F4507BE036FC ON bovin_shipment (shipment_id)');
|
||||
$this->addSql('CREATE INDEX IDX_7049F4502EE48A36 ON bovin_shipment (shipment_type_id)');
|
||||
$this->addSql('CREATE TABLE customer (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE TABLE customer_address (customer_id INT NOT NULL, address_id INT NOT NULL, PRIMARY KEY (customer_id, address_id))');
|
||||
$this->addSql('CREATE INDEX IDX_1193CB3F9395C3F3 ON customer_address (customer_id)');
|
||||
$this->addSql('CREATE INDEX IDX_1193CB3FF5B7AF75 ON customer_address (address_id)');
|
||||
$this->addSql('CREATE TABLE shipment (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, licence_plate VARCHAR(255) NOT NULL, identification_number VARCHAR(20) DEFAULT NULL, current_step INT DEFAULT 0 NOT NULL, is_valid BOOLEAN NOT NULL, shipment_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, carrier_id INT DEFAULT NULL, vehicle_id INT DEFAULT NULL, truck_id INT DEFAULT NULL, customer_id INT DEFAULT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_2CB20DC347639A5 ON shipment (identification_number)');
|
||||
$this->addSql('CREATE INDEX IDX_2CB20DC21DFC797 ON shipment (carrier_id)');
|
||||
$this->addSql('CREATE INDEX IDX_2CB20DC545317D1 ON shipment (vehicle_id)');
|
||||
$this->addSql('CREATE INDEX IDX_2CB20DCC6957CCE ON shipment (truck_id)');
|
||||
$this->addSql('CREATE INDEX IDX_2CB20DC9395C3F3 ON shipment (customer_id)');
|
||||
$this->addSql('CREATE TABLE shipment_type (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, label VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
|
||||
$this->addSql('ALTER TABLE bovin_shipment ADD CONSTRAINT FK_7049F4507BE036FC FOREIGN KEY (shipment_id) REFERENCES shipment (id)');
|
||||
$this->addSql('ALTER TABLE bovin_shipment ADD CONSTRAINT FK_7049F4502EE48A36 FOREIGN KEY (shipment_type_id) REFERENCES shipment_type (id)');
|
||||
$this->addSql('ALTER TABLE customer_address ADD CONSTRAINT FK_1193CB3F9395C3F3 FOREIGN KEY (customer_id) REFERENCES customer (id) ON DELETE CASCADE');
|
||||
$this->addSql('ALTER TABLE customer_address ADD CONSTRAINT FK_1193CB3FF5B7AF75 FOREIGN KEY (address_id) REFERENCES address (id) ON DELETE CASCADE');
|
||||
$this->addSql('ALTER TABLE shipment ADD CONSTRAINT FK_2CB20DC21DFC797 FOREIGN KEY (carrier_id) REFERENCES carrier (id) NOT DEFERRABLE');
|
||||
$this->addSql('ALTER TABLE shipment ADD CONSTRAINT FK_2CB20DC545317D1 FOREIGN KEY (vehicle_id) REFERENCES vehicle (id)');
|
||||
$this->addSql('ALTER TABLE shipment ADD CONSTRAINT FK_2CB20DCC6957CCE FOREIGN KEY (truck_id) REFERENCES truck (id) NOT DEFERRABLE');
|
||||
$this->addSql('ALTER TABLE shipment ADD CONSTRAINT FK_2CB20DC9395C3F3 FOREIGN KEY (customer_id) REFERENCES customer (id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE bovin_shipment DROP CONSTRAINT FK_7049F4507BE036FC');
|
||||
$this->addSql('ALTER TABLE bovin_shipment DROP CONSTRAINT FK_7049F4502EE48A36');
|
||||
$this->addSql('ALTER TABLE customer_address DROP CONSTRAINT FK_1193CB3F9395C3F3');
|
||||
$this->addSql('ALTER TABLE customer_address DROP CONSTRAINT FK_1193CB3FF5B7AF75');
|
||||
$this->addSql('ALTER TABLE shipment DROP CONSTRAINT FK_2CB20DC21DFC797');
|
||||
$this->addSql('ALTER TABLE shipment DROP CONSTRAINT FK_2CB20DC545317D1');
|
||||
$this->addSql('ALTER TABLE shipment DROP CONSTRAINT FK_2CB20DCC6957CCE');
|
||||
$this->addSql('ALTER TABLE shipment DROP CONSTRAINT FK_2CB20DC9395C3F3');
|
||||
$this->addSql('DROP TABLE bovin_shipment');
|
||||
$this->addSql('DROP TABLE customer');
|
||||
$this->addSql('DROP TABLE customer_address');
|
||||
$this->addSql('DROP TABLE shipment');
|
||||
$this->addSql('DROP TABLE shipment_type');
|
||||
}
|
||||
}
|
||||
35
migrations/Version20260204102423.php
Normal file
35
migrations/Version20260204102423.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260204102423 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE shipment DROP CONSTRAINT fk_2cb20dc545317d1');
|
||||
$this->addSql('DROP INDEX idx_2cb20dc545317d1');
|
||||
$this->addSql('ALTER TABLE shipment DROP vehicle_id');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE shipment ADD vehicle_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE shipment ADD CONSTRAINT fk_2cb20dc545317d1 FOREIGN KEY (vehicle_id) REFERENCES vehicle (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX idx_2cb20dc545317d1 ON shipment (vehicle_id)');
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260204141406 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE reception_bovine ALTER quantity SET DEFAULT 0');
|
||||
$this->addSql('CREATE UNIQUE INDEX uniq_reception_bovine_type ON reception_bovine (reception_id, bovine_type_id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP INDEX uniq_reception_bovine_type');
|
||||
$this->addSql('ALTER TABLE reception_bovine ALTER quantity DROP DEFAULT');
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260205070819 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE reception ADD bovine_detail VARCHAR(255) DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE reception DROP bovine_detail');
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\ApiResource;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use App\State\AppVersionProvider;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new Get(
|
||||
uriTemplate: '/version',
|
||||
normalizationContext: ['groups' => ['version:read']],
|
||||
provider: AppVersionProvider::class,
|
||||
),
|
||||
],
|
||||
)]
|
||||
final class AppVersion
|
||||
{
|
||||
#[Groups(['version:read'])]
|
||||
public string $version = '';
|
||||
}
|
||||
0
src/Entity/.gitignore
vendored
Normal file
0
src/Entity/.gitignore
vendored
Normal file
@@ -35,27 +35,27 @@ class Address
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 120)]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read'])]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read', 'customer:read', 'shipment:read'])]
|
||||
private string $label = '';
|
||||
|
||||
#[ORM\Column(length: 180)]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read'])]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read', 'customer:read', 'shipment:read'])]
|
||||
private string $street = '';
|
||||
|
||||
#[ORM\Column(name: 'street2', length: 180, nullable: true)]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read'])]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read', 'customer:read', 'shipment:read'])]
|
||||
private ?string $street2 = null;
|
||||
|
||||
#[ORM\Column(name: 'postal_code', length: 20)]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read'])]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read', 'customer:read', 'shipment:read'])]
|
||||
private string $postalCode = '';
|
||||
|
||||
#[ORM\Column(length: 120)]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read'])]
|
||||
#[Groups(['address:read', 'supplier:read', 'reception:read', 'customer:read', 'shipment:read'])]
|
||||
private string $city = '';
|
||||
|
||||
#[ORM\Column(name: 'country_code', length: 2)]
|
||||
#[Groups(['address:read', 'supplier:read'])]
|
||||
#[Groups(['address:read', 'supplier:read', 'customer:read'])]
|
||||
private string $countryCode = '';
|
||||
|
||||
/**
|
||||
|
||||
101
src/Entity/BovinShipment.php
Normal file
101
src/Entity/BovinShipment.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'bovin_shipment')]
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new Get(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['bovin-shipment:read']],
|
||||
),
|
||||
new GetCollection(
|
||||
normalizationContext: ['groups' => ['bovin-shipment:read']],
|
||||
),
|
||||
|
||||
// new Get(
|
||||
// uriTemplate: '/receptions/weigh',
|
||||
// openapi: new OpenApiOperation(
|
||||
// summary: 'Fetch the current weight reading',
|
||||
// description: 'Queries the pont-bascule and returns the weight data.',
|
||||
// ),
|
||||
// normalizationContext: ['groups' => ['reception:weigh:read']],
|
||||
// output: PontBasculeReading::class,
|
||||
// provider: ReceptionWeighingProvider::class,
|
||||
// ),
|
||||
// new Get(
|
||||
// uriTemplate: '/receptions/{id}/receipt',
|
||||
// requirements: ['id' => '\d+'],
|
||||
// openapi: new OpenApiOperation(
|
||||
// summary: 'Render a reception receipt',
|
||||
// description: 'Returns a PDF receipt for the reception.',
|
||||
// ),
|
||||
// output: false,
|
||||
// provider: ReceptionReceiptProvider::class,
|
||||
// ),
|
||||
],
|
||||
)]
|
||||
class BovinShipment
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['shipment:read', 'bovine-shipment:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'shipment_types')]
|
||||
#[Groups(['bovine-shipment:read'])]
|
||||
private ?Shipment $shipment = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[Groups(['shipment:read', 'bovine-shipment:read'])]
|
||||
private ?ShipmentType $shipmentType = null;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Groups(['shipment:read', 'bovine-shipment:read'])]
|
||||
private ?int $nbBovinSend = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getShipment(): ?Shipment
|
||||
{
|
||||
return $this->shipment;
|
||||
}
|
||||
|
||||
public function setShipment(?Shipment $shipment): void
|
||||
{
|
||||
$this->shipment = $shipment;
|
||||
}
|
||||
|
||||
public function getShipmentType(): ?ShipmentType
|
||||
{
|
||||
return $this->shipmentType;
|
||||
}
|
||||
|
||||
public function setShipmentType(?ShipmentType $shipmentType): void
|
||||
{
|
||||
$this->shipmentType = $shipmentType;
|
||||
}
|
||||
|
||||
public function getNbBovinSend(): ?int
|
||||
{
|
||||
return $this->nbBovinSend;
|
||||
}
|
||||
|
||||
public function setNbBovinSend(?int $nbBovinSend): void
|
||||
{
|
||||
$this->nbBovinSend = $nbBovinSend;
|
||||
}
|
||||
}
|
||||
@@ -29,15 +29,15 @@ class Carrier
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read'])]
|
||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read', 'shipment:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 180)]
|
||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read'])]
|
||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read', 'shipment:read'])]
|
||||
private string $name = '';
|
||||
|
||||
#[ORM\Column(length: 30, nullable: true)]
|
||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read'])]
|
||||
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read', 'shipment:read'])]
|
||||
private ?string $code = null;
|
||||
|
||||
public function getId(): ?int
|
||||
|
||||
94
src/Entity/Customer.php
Normal file
94
src/Entity/Customer.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'customer')]
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new Get(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['customer:read']],
|
||||
),
|
||||
new GetCollection(
|
||||
normalizationContext: ['groups' => ['customer:read']],
|
||||
),
|
||||
],
|
||||
security: "is_granted('ROLE_USER')",
|
||||
)]
|
||||
class Customer
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['shipment:read', 'customer:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Groups(['customer:read', 'shipment:read'])]
|
||||
private ?string $label = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Groups(['customer:read', 'shipment:read'])]
|
||||
private ?string $code = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Address>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Address::class, inversedBy: 'customers')]
|
||||
#[ORM\JoinTable(name: 'customer_address')]
|
||||
#[Groups(['customer:read'])]
|
||||
#[ApiProperty(readableLink: true)]
|
||||
private Collection $addresses;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->addresses = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setLabel(?string $label): void
|
||||
{
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function getCode(): ?string
|
||||
{
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setCode(?string $code): void
|
||||
{
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
public function getAddresses(): Collection
|
||||
{
|
||||
return $this->addresses;
|
||||
}
|
||||
|
||||
public function setAddresses(Collection $addresses): void
|
||||
{
|
||||
$this->addresses = $addresses;
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Doctrine\Orm\Filter\BooleanFilter;
|
||||
use ApiPlatform\Metadata\ApiFilter;
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
@@ -28,7 +26,6 @@ use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
#[ORM\Entity]
|
||||
#[ORM\HasLifecycleCallbacks]
|
||||
#[ORM\Table(name: 'reception')]
|
||||
#[ApiFilter(BooleanFilter::class, properties: ['isValid'])]
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new Get(
|
||||
@@ -75,27 +72,27 @@ class Reception
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['reception:read', 'reception-bovine:read'])]
|
||||
#[Groups(['reception:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 20, nullable: true)]
|
||||
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||
#[Groups(['reception:read', 'reception:write'])]
|
||||
private ?string $licensePlate = null;
|
||||
|
||||
#[ORM\Column(length: 20, unique: true, nullable: true)]
|
||||
#[Groups(['reception:read', 'reception-bovine:read'])]
|
||||
#[Groups(['reception:read'])]
|
||||
private ?string $identificationNumber = null;
|
||||
|
||||
#[ORM\Column(options: ['default' => 0])]
|
||||
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||
#[Groups(['reception:read', 'reception:write'])]
|
||||
private int $currentStep = 0;
|
||||
|
||||
#[ORM\Column(options: ['default' => false])]
|
||||
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||
#[Groups(['reception:read', 'reception:write'])]
|
||||
private bool $isValid = false;
|
||||
|
||||
#[ORM\Column(name: 'date_reception', type: 'datetime_immutable')]
|
||||
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||
#[Groups(['reception:read', 'reception:write'])]
|
||||
#[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
|
||||
private ?DateTimeImmutable $receptionDate = null;
|
||||
|
||||
@@ -171,20 +168,6 @@ class Reception
|
||||
#[ApiProperty(readableLink: true)]
|
||||
private ?Driver $driver = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, ReceptionBovine>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: ReceptionBovine::class, mappedBy: 'reception', cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
#[Assert\Range(
|
||||
min: 0
|
||||
)]
|
||||
#[Groups(['reception:read', 'reception:write'])]
|
||||
private Collection $bovines_types;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[Groups(['reception:read', 'reception:write'])]
|
||||
private ?string $bovineDetail = null;
|
||||
|
||||
public function __construct(
|
||||
?DateTimeImmutable $receptionDate = null,
|
||||
) {
|
||||
@@ -192,7 +175,6 @@ class Reception
|
||||
$this->weights = new ArrayCollection();
|
||||
$this->buildings = new ArrayCollection();
|
||||
$this->pelletBuildings = new ArrayCollection();
|
||||
$this->bovines_types = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
@@ -487,46 +469,4 @@ class Reception
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, ReceptionBovine>
|
||||
*/
|
||||
public function getBovinesTypes(): Collection
|
||||
{
|
||||
return $this->bovines_types;
|
||||
}
|
||||
|
||||
public function addBovinesType(ReceptionBovine $bovinesType): static
|
||||
{
|
||||
if (!$this->bovines_types->contains($bovinesType)) {
|
||||
$this->bovines_types->add($bovinesType);
|
||||
$bovinesType->setReception($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeBovinesType(ReceptionBovine $bovinesType): static
|
||||
{
|
||||
if ($this->bovines_types->removeElement($bovinesType)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($bovinesType->getReception() === $this) {
|
||||
$bovinesType->setReception(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBovineDetail(): ?string
|
||||
{
|
||||
return $this->bovineDetail;
|
||||
}
|
||||
|
||||
public function setBovineDetail(?string $bovineDetail): static
|
||||
{
|
||||
$this->bovineDetail = $bovineDetail;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
|
||||
use ApiPlatform\Metadata\ApiFilter;
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Delete;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ApiFilter(SearchFilter::class, properties: ['reception' => 'exact'])]
|
||||
#[ORM\UniqueConstraint(name: 'uniq_reception_bovine_type', columns: ['reception_id', 'bovine_type_id'])]
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new Get(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['reception-bovine:read']],
|
||||
),
|
||||
new GetCollection(
|
||||
normalizationContext: ['groups' => ['reception-bovine:read']],
|
||||
),
|
||||
new Post(
|
||||
normalizationContext: ['groups' => ['reception-bovine:read']],
|
||||
denormalizationContext: ['groups' => ['reception-bovine:write']],
|
||||
),
|
||||
new Patch(
|
||||
normalizationContext: ['groups' => ['reception-bovine:read']],
|
||||
denormalizationContext: ['groups' => ['reception-bovine:write']],
|
||||
),
|
||||
new Delete(),
|
||||
],
|
||||
security: "is_granted('ROLE_USER')",
|
||||
)]
|
||||
class ReceptionBovine
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['reception-bovine:read', 'reception:read'])]
|
||||
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'bovines_types')]
|
||||
#[Groups(['reception-bovine:read', 'reception-bovine:write'])]
|
||||
private ?Reception $reception = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
#[Groups(['reception-bovine:read', 'reception-bovine:write', 'reception:read'])]
|
||||
#[ApiProperty(readableLink: true)]
|
||||
private ?BovineType $bovineType = null;
|
||||
|
||||
#[ORM\Column(options: ['default' => 0])]
|
||||
#[Assert\Range(
|
||||
min: 0
|
||||
)]
|
||||
#[Groups(['reception-bovine:read', 'reception-bovine:write', 'reception:read'])]
|
||||
private ?int $quantity = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getReception(): ?Reception
|
||||
{
|
||||
return $this->reception;
|
||||
}
|
||||
|
||||
public function setReception(?Reception $reception): static
|
||||
{
|
||||
$this->reception = $reception;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBovineType(): ?BovineType
|
||||
{
|
||||
return $this->bovineType;
|
||||
}
|
||||
|
||||
public function setBovineType(?BovineType $bovineType): static
|
||||
{
|
||||
$this->bovineType = $bovineType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuantity(): ?int
|
||||
{
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
public function setQuantity(int $quantity): static
|
||||
{
|
||||
$this->quantity = $quantity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
244
src/Entity/Shipment.php
Normal file
244
src/Entity/Shipment.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
use ApiPlatform\Metadata\ApiResource;
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Patch;
|
||||
use ApiPlatform\Metadata\Post;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Context;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'shipment')]
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new Get(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['shipment:read']],
|
||||
),
|
||||
new GetCollection(
|
||||
normalizationContext: ['groups' => ['shipment:read']],
|
||||
),
|
||||
new Post(
|
||||
normalizationContext: ['groups' => ['shipment:read']],
|
||||
denormalizationContext: ['groups' => ['shipment:write']],
|
||||
),
|
||||
new Patch(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['shipment:read']],
|
||||
denormalizationContext: ['groups' => ['shipment:write']],
|
||||
),
|
||||
// new Get(
|
||||
// uriTemplate: '/shipments/weigh',
|
||||
// openapi: new OpenApiOperation(
|
||||
// summary: 'Fetch the current weight reading',
|
||||
// description: 'Queries the pont-bascule and returns the weight data.',
|
||||
// ),
|
||||
// normalizationContext: ['groups' => ['shipment:weigh:read']],
|
||||
// output: PontBasculeReading::class,
|
||||
// provider: shipmentWeighingProvider::class,
|
||||
// ),
|
||||
// new Get(
|
||||
// uriTemplate: '/shipments/{id}/receipt',
|
||||
// requirements: ['id' => '\d+'],
|
||||
// openapi: new OpenApiOperation(
|
||||
// summary: 'Render a shipment receipt',
|
||||
// description: 'Returns a PDF receipt for the shipment.',
|
||||
// ),
|
||||
// output: false,
|
||||
// provider: shipmentReceiptProvider::class,
|
||||
// ),
|
||||
],
|
||||
)]
|
||||
class Shipment
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['shipment:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
private ?string $licencePlate = null;
|
||||
|
||||
#[ORM\Column(length: 20, unique: true, nullable: true)]
|
||||
#[Groups(['shipment:read'])]
|
||||
private ?string $identificationNumber = null;
|
||||
|
||||
#[ORM\Column(options: ['default' => 0])]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
private int $currentStep = 0;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
private ?bool $isValid = null;
|
||||
|
||||
#[ORM\Column(name: 'shipment_date', type: 'datetime_immutable')]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
#[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
|
||||
private ?DateTimeImmutable $shipmentDate = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
#[ApiProperty(readableLink: true)]
|
||||
private ?Carrier $carrier = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
#[ApiProperty(readableLink: true)]
|
||||
private ?Truck $truck = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
private ?Customer $customer = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, BovinShipment>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: BovinShipment::class, mappedBy: 'shipment')]
|
||||
#[Groups(['shipment:read', 'shipment:write'])]
|
||||
private Collection $bovinShipments;
|
||||
|
||||
public function __construct(Collection $bovinShipments)
|
||||
{
|
||||
$this->bovinShipments = $bovinShipments;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getLicencePlate(): ?string
|
||||
{
|
||||
return $this->licencePlate;
|
||||
}
|
||||
|
||||
public function setLicencePlate(?string $licencePlate): void
|
||||
{
|
||||
$this->licencePlate = $licencePlate;
|
||||
}
|
||||
|
||||
public function getIdentificationNumber(): ?string
|
||||
{
|
||||
return $this->identificationNumber;
|
||||
}
|
||||
|
||||
public function setIdentificationNumber(?string $identificationNumber): void
|
||||
{
|
||||
$this->identificationNumber = $identificationNumber;
|
||||
}
|
||||
|
||||
public function getCurrentStep(): int
|
||||
{
|
||||
return $this->currentStep;
|
||||
}
|
||||
|
||||
public function setCurrentStep(int $currentStep): void
|
||||
{
|
||||
$this->currentStep = $currentStep;
|
||||
}
|
||||
|
||||
public function getIsValid(): ?bool
|
||||
{
|
||||
return $this->isValid;
|
||||
}
|
||||
|
||||
public function setIsValid(?bool $isValid): void
|
||||
{
|
||||
$this->isValid = $isValid;
|
||||
}
|
||||
|
||||
public function getShipmentDate(): ?DateTimeImmutable
|
||||
{
|
||||
return $this->shipmentDate;
|
||||
}
|
||||
|
||||
public function setShipmentDate(?DateTimeImmutable $shipmentDate): void
|
||||
{
|
||||
$this->shipmentDate = $shipmentDate;
|
||||
}
|
||||
|
||||
public function getCarrier(): ?Carrier
|
||||
{
|
||||
return $this->carrier;
|
||||
}
|
||||
|
||||
public function setCarrier(?Carrier $carrier): void
|
||||
{
|
||||
$this->carrier = $carrier;
|
||||
}
|
||||
|
||||
public function getVehicle(): ?Vehicle
|
||||
{
|
||||
return $this->vehicle;
|
||||
}
|
||||
|
||||
public function setVehicle(?Vehicle $vehicle): void
|
||||
{
|
||||
$this->vehicle = $vehicle;
|
||||
}
|
||||
|
||||
public function getTruck(): ?Truck
|
||||
{
|
||||
return $this->truck;
|
||||
}
|
||||
|
||||
public function setTruck(?Truck $truck): void
|
||||
{
|
||||
$this->truck = $truck;
|
||||
}
|
||||
|
||||
public function getCustomer(): ?Customer
|
||||
{
|
||||
return $this->customer;
|
||||
}
|
||||
|
||||
public function setCustomer(?Customer $customer): void
|
||||
{
|
||||
$this->customer = $customer;
|
||||
}
|
||||
|
||||
public function getBovinShipments(): Collection
|
||||
{
|
||||
return $this->bovinShipments;
|
||||
}
|
||||
|
||||
public function setBovinShipments(Collection $bovinShipments): void
|
||||
{
|
||||
$this->bovinShipments = $bovinShipments;
|
||||
}
|
||||
|
||||
public function addPelletBuilding(BovinShipment $bovinShipments): self
|
||||
{
|
||||
if (!$this->bovinShipments->contains($bovinShipments)) {
|
||||
$this->bovinShipments->add($bovinShipments);
|
||||
$bovinShipments->setReception($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removePelletBuilding(BovinShipment $bovinShipments): self
|
||||
{
|
||||
if ($this->bovinShipments->removeElement($bovinShipments)) {
|
||||
if ($bovinShipments->getReception() === $this) {
|
||||
$bovinShipments->setReception(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -11,32 +11,33 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Attribute\Groups;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'shipment_type')]
|
||||
#[ApiResource(
|
||||
operations: [
|
||||
new Get(
|
||||
requirements: ['id' => '\d+'],
|
||||
normalizationContext: ['groups' => ['bovine-type:read']],
|
||||
normalizationContext: ['groups' => ['shipment-type:read']],
|
||||
),
|
||||
new GetCollection(
|
||||
normalizationContext: ['groups' => ['bovine-type:read']],
|
||||
normalizationContext: ['groups' => ['shipment-type:read']],
|
||||
),
|
||||
],
|
||||
security: "is_granted('ROLE_USER')",
|
||||
)]
|
||||
class BovineType
|
||||
class ShipmentType
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
#[Groups(['bovine-type:read', 'reception:read', 'reception-bovine:read'])]
|
||||
#[Groups(['shipment-type:read', 'shipment:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 120)]
|
||||
#[Groups(['bovine-type:read', 'reception:read', 'reception-bovine:read'])]
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Groups(['shipment-type:read', 'shipment:read'])]
|
||||
private ?string $label = null;
|
||||
|
||||
#[ORM\Column(length: 50)]
|
||||
#[Groups(['bovine-type:read', 'reception:read', 'reception-bovine:read'])]
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Groups(['shipment-type:read', 'shipment:read'])]
|
||||
private ?string $code = null;
|
||||
|
||||
public function getId(): ?int
|
||||
@@ -61,7 +62,7 @@ class BovineType
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setCode(string $code): static
|
||||
public function setCode(string $code): self
|
||||
{
|
||||
$this->code = $code;
|
||||
|
||||
0
src/Repository/.gitignore
vendored
Normal file
0
src/Repository/.gitignore
vendored
Normal file
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\State;
|
||||
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use App\ApiResource\AppVersion;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
final readonly class AppVersionProvider implements ProviderInterface
|
||||
{
|
||||
public function __construct(
|
||||
#[Autowire('%app.version%')]
|
||||
private string $version,
|
||||
) {}
|
||||
|
||||
public function provide(Operation $operation, array $uriVariables = [], array $context = []): AppVersion
|
||||
{
|
||||
$dto = new AppVersion();
|
||||
$dto->version = $this->version;
|
||||
|
||||
return $dto;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user