Compare commits
11 Commits
6421419812
...
feat/test-
| Author | SHA1 | Date | |
|---|---|---|---|
| 92354d9060 | |||
| 33563addbe | |||
| 81c2a5802b | |||
| 015a8c49fb | |||
| 505f67d475 | |||
| 13e8698673 | |||
| a34bdbfe8d | |||
| d8e1cdc72c | |||
| 2c54a8c950 | |||
| 7c85d91c78 | |||
| 149bced1c5 |
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.ask.xml
generated
Normal file
6
.idea/copilot.data.migration.ask.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AskMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal file
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Ask2AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.edit.xml
generated
Normal file
6
.idea/copilot.data.migration.edit.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="EditMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
2
.idea/dataSources.xml
generated
2
.idea/dataSources.xml
generated
@@ -5,7 +5,7 @@
|
|||||||
<driver-ref>postgresql</driver-ref>
|
<driver-ref>postgresql</driver-ref>
|
||||||
<synchronize>true</synchronize>
|
<synchronize>true</synchronize>
|
||||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||||
<jdbc-url>jdbc:postgresql://localhost:5433/ferme</jdbc-url>
|
<jdbc-url>jdbc:postgresql://localhost:5432/ferme</jdbc-url>
|
||||||
<working-dir>$ProjectFileDir$</working-dir>
|
<working-dir>$ProjectFileDir$</working-dir>
|
||||||
</data-source>
|
</data-source>
|
||||||
<data-source source="LOCAL" name="Ferme recette" uuid="ae622167-c834-4e7b-87a5-c1721036f5dc">
|
<data-source source="LOCAL" name="Ferme recette" uuid="ae622167-c834-4e7b-87a5-c1721036f5dc">
|
||||||
|
|||||||
7
.idea/data_source_mapping.xml
generated
7
.idea/data_source_mapping.xml
generated
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="DataSourcePerFileMappings">
|
|
||||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/ae622167-c834-4e7b-87a5-c1721036f5dc/console.sql" value="ae622167-c834-4e7b-87a5-c1721036f5dc" />
|
|
||||||
<file url="file://$APPLICATION_CONFIG_DIR$/consoles/db/f407a514-c6b4-4b26-9555-445a85892502/console.sql" value="f407a514-c6b4-4b26-9555-445a85892502" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
1
.idea/ferme.iml
generated
1
.idea/ferme.iml
generated
@@ -154,6 +154,7 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/web-profiler-bundle" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/web-profiler-bundle" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/data-fixtures" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/data-fixtures" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/maker-bundle" />
|
||||||
<excludePattern pattern="reference.php" />
|
<excludePattern pattern="reference.php" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|||||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<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>
|
||||||
23
.idea/php.xml
generated
23
.idea/php.xml
generated
@@ -4,12 +4,24 @@
|
|||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PHPCSFixerOptionsConfiguration">
|
<component name="PHPCSFixerOptionsConfiguration">
|
||||||
|
<option name="codingStandard" value="Custom" />
|
||||||
|
<option name="rulesetPath" value="$PROJECT_DIR$/.php-cs-fixer.dist.php" />
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||||
<option name="highlightLevel" value="WARNING" />
|
<option name="highlightLevel" value="WARNING" />
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="PhpCSFixer">
|
||||||
|
<phpcsfixer_settings>
|
||||||
|
<PhpCSFixerConfiguration tool_path="$PROJECT_DIR$/vendor/bin/php-cs-fixer" />
|
||||||
|
</phpcsfixer_settings>
|
||||||
|
</component>
|
||||||
|
<component name="PhpCodeSniffer">
|
||||||
|
<phpcs_settings>
|
||||||
|
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="8475dcce-5d1d-4a2c-9e2f-7454868f1931" timeout="30000" />
|
||||||
|
</phpcs_settings>
|
||||||
|
</component>
|
||||||
<component name="PhpIncludePathManager">
|
<component name="PhpIncludePathManager">
|
||||||
<include_path>
|
<include_path>
|
||||||
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||||
@@ -160,9 +172,15 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/malio/ednotif-bundle" />
|
<path value="$PROJECT_DIR$/vendor/malio/ednotif-bundle" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.4" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.4" />
|
||||||
|
<component name="PhpStan">
|
||||||
|
<PhpStan_settings>
|
||||||
|
<phpstan_by_interpreter asDefaultInterpreter="true" interpreter_id="8475dcce-5d1d-4a2c-9e2f-7454868f1931" timeout="60000" />
|
||||||
|
</PhpStan_settings>
|
||||||
|
</component>
|
||||||
<component name="PhpStanOptionsConfiguration">
|
<component name="PhpStanOptionsConfiguration">
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
@@ -171,6 +189,11 @@
|
|||||||
<PhpUnitSettings custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" />
|
<PhpUnitSettings custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" />
|
||||||
</phpunit_settings>
|
</phpunit_settings>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="Psalm">
|
||||||
|
<Psalm_settings>
|
||||||
|
<psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="8475dcce-5d1d-4a2c-9e2f-7454868f1931" timeout="60000" />
|
||||||
|
</Psalm_settings>
|
||||||
|
</component>
|
||||||
<component name="PsalmOptionsConfiguration">
|
<component name="PsalmOptionsConfiguration">
|
||||||
<option name="transferred" value="true" />
|
<option name="transferred" value="true" />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
131
.idea/workspace.xml
generated
131
.idea/workspace.xml
generated
@@ -4,15 +4,15 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="fix : correction du téléchargement du bon de réception pour Chrome">
|
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||||
<change afterPath="$PROJECT_DIR$/frontend/pages/identification-bovin.vue" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/frontend/services/dto/identification-bovin-data.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/frontend/services/identification-bovin.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/config/reference.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/reference.php" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/config/reference.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/reference.php" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/frontend/i18n/locales/fr.json" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/i18n/locales/fr.json" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/frontend/components/reception/reception-bovine-received.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/reception/reception-bovine-received.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/components/reception/reception-form.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/reception/reception-form.vue" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/ApiResource/BovinIdentification.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/ApiResource/BovinIdentification.php" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/frontend/components/reception/reception-product-received.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/reception/reception-product-received.vue" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/frontend/services/dto/reception-data.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/services/dto/reception-data.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/Entity/Reception.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/Reception.php" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/Entity/ReceptionBovine.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Entity/ReceptionBovine.php" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -23,6 +23,11 @@
|
|||||||
<pharConfigPath>$PROJECT_DIR$/composer.json</pharConfigPath>
|
<pharConfigPath>$PROJECT_DIR$/composer.json</pharConfigPath>
|
||||||
<execution />
|
<execution />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="CopilotPersistence">
|
||||||
|
<persistenceIdMap>
|
||||||
|
<entry key="_//wsl.localhost/Ubuntu-24.04/home/kevin/Stage/Ferme" value="381AhnCm9yPeOiWgMObKHhtgv2C" />
|
||||||
|
</persistenceIdMap>
|
||||||
|
</component>
|
||||||
<component name="EmbeddingIndexingInfo">
|
<component name="EmbeddingIndexingInfo">
|
||||||
<option name="cachedIndexableFilesCount" value="151" />
|
<option name="cachedIndexableFilesCount" value="151" />
|
||||||
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
||||||
@@ -38,7 +43,7 @@
|
|||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||||
<map>
|
<map>
|
||||||
<entry key="$PROJECT_DIR$" value="develop" />
|
<entry key="$PROJECT_DIR$" value="fix/makefile" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
@@ -56,7 +61,7 @@
|
|||||||
</server>
|
</server>
|
||||||
</servers>
|
</servers>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpWorkspaceProjectConfiguration">
|
<component name="PhpWorkspaceProjectConfiguration" interpreter_name="C:/php-8.4.3/php.exe">
|
||||||
<include_path>
|
<include_path>
|
||||||
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||||
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
|
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
|
||||||
@@ -206,6 +211,7 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/malio/ednotif-bundle" />
|
<path value="$PROJECT_DIR$/vendor/malio/ednotif-bundle" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectColorInfo">{
|
<component name="ProjectColorInfo">{
|
||||||
@@ -218,34 +224,36 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||||
"git-widget-placeholder": "feat/poc-identification-bovin",
|
"git-widget-placeholder": "feat/256-reception-etape-3-bovin",
|
||||||
"node.js.detected.package.eslint": "true",
|
"last_opened_file_path": "/home/sroy/Documents/test/Ferme",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
"nodejs_package_manager_path": "npm",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"settings.editor.selected.configurable": "configurable.tailwindcss",
|
||||||
|
"ts.external.directory.path": "/opt/phpstorm/plugins/javascript-plugin/jsLanguageServicesImpl/external",
|
||||||
|
"vue.rearranger.settings.migration": "true"
|
||||||
},
|
},
|
||||||
"keyToStringList": {
|
"keyToStringList": {
|
||||||
"DatabaseDriversLRU": [
|
"DatabaseDriversLRU": [
|
||||||
"postgresql"
|
"postgresql"
|
||||||
],
|
],
|
||||||
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [
|
"com.intellij.ide.scratch.ScratchImplUtil$2/New Scratch File": [
|
||||||
"TEXT"
|
"TEXT"
|
||||||
],
|
],
|
||||||
"vue.recent.templates": [
|
"vue.recent.templates": [
|
||||||
"Vue Composition API Component"
|
"Vue Composition API Component"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}]]></component>
|
}</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\m-tristan\workspace\Ferme" />
|
<recent name="\\wsl.localhost\Ubuntu-24.04\home\m-tristan\workspace\Ferme" />
|
||||||
@@ -281,7 +289,17 @@
|
|||||||
<workItem from="1769612160652" duration="23952000" />
|
<workItem from="1769612160652" duration="23952000" />
|
||||||
<workItem from="1769696465294" duration="8573000" />
|
<workItem from="1769696465294" duration="8573000" />
|
||||||
<workItem from="1769756623432" duration="21592000" />
|
<workItem from="1769756623432" duration="21592000" />
|
||||||
<workItem from="1770015653091" duration="9682000" />
|
<workItem from="1770015653091" duration="73000" />
|
||||||
|
<workItem from="1770040138216" duration="6492000" />
|
||||||
|
<workItem from="1770050834470" duration="1873000" />
|
||||||
|
<workItem from="1770054381680" duration="1292000" />
|
||||||
|
<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" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="feat : Ajout de pinia, création de la table weight et reception mise en place du système de step pour les receptions (WIP)">
|
<task id="LOCAL-00001" summary="feat : Ajout de pinia, création de la table weight et reception mise en place du système de step pour les receptions (WIP)">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
@@ -651,15 +669,31 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1769782099473</updated>
|
<updated>1769782099473</updated>
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00047" summary="fix : correction du téléchargement du bon de réception pour Chrome">
|
<task id="LOCAL-00047" summary="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
<created>1770015863605</created>
|
<created>1770131226364</created>
|
||||||
<option name="number" value="00047" />
|
<option name="number" value="00047" />
|
||||||
<option name="presentableId" value="LOCAL-00047" />
|
<option name="presentableId" value="LOCAL-00047" />
|
||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1770015863605</updated>
|
<updated>1770131226364</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="48" />
|
<task id="LOCAL-00048" summary="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1770206668867</created>
|
||||||
|
<option name="number" value="00048" />
|
||||||
|
<option name="presentableId" value="LOCAL-00048" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1770206668867</updated>
|
||||||
|
</task>
|
||||||
|
<task id="LOCAL-00049" summary="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1770217875423</created>
|
||||||
|
<option name="number" value="00049" />
|
||||||
|
<option name="presentableId" value="LOCAL-00049" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1770217875423</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="50" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@@ -733,11 +767,30 @@
|
|||||||
<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 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 : ajout de colonne pour les Supplier, Address. Modification du numéro de réception et ajout de fixtures" />
|
||||||
<MESSAGE value="feat : mise à jour du bon de réception" />
|
<MESSAGE value="feat : mise à jour du bon de réception" />
|
||||||
<MESSAGE value="fix : correction du téléchargement du bon de réception pour Chrome" />
|
<MESSAGE value="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="fix : correction du téléchargement du bon de réception pour Chrome" />
|
<option name="LAST_COMMIT_MESSAGE" value="feat : Ajout de la sélection des bovins étape 3 d'une réception (WIP)" />
|
||||||
|
</component>
|
||||||
|
<component name="XDebuggerManager">
|
||||||
|
<breakpoint-manager>
|
||||||
|
<breakpoints>
|
||||||
|
<line-breakpoint enabled="true" type="php">
|
||||||
|
<url>file://$PROJECT_DIR$/src/Entity/ReceptionPelletBuilding.php</url>
|
||||||
|
<line>6</line>
|
||||||
|
<option name="timeStamp" value="3" />
|
||||||
|
</line-breakpoint>
|
||||||
|
</breakpoints>
|
||||||
|
</breakpoint-manager>
|
||||||
</component>
|
</component>
|
||||||
<component name="XSLT-Support.FileAssociations.UIState">
|
<component name="XSLT-Support.FileAssociations.UIState">
|
||||||
<expand />
|
<expand />
|
||||||
<select />
|
<select />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="github-copilot-workspace">
|
||||||
|
<instructionFileLocations>
|
||||||
|
<option value=".github/instructions" />
|
||||||
|
</instructionFileLocations>
|
||||||
|
<promptFileLocations>
|
||||||
|
<option value=".github/prompts" />
|
||||||
|
</promptFileLocations>
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -93,6 +93,7 @@
|
|||||||
"phpunit/phpunit": "^12.5",
|
"phpunit/phpunit": "^12.5",
|
||||||
"symfony/browser-kit": "8.0.*",
|
"symfony/browser-kit": "8.0.*",
|
||||||
"symfony/css-selector": "8.0.*",
|
"symfony/css-selector": "8.0.*",
|
||||||
|
"symfony/maker-bundle": "^1.65",
|
||||||
"symfony/stopwatch": "8.0.*",
|
"symfony/stopwatch": "8.0.*",
|
||||||
"symfony/web-profiler-bundle": "8.0.*"
|
"symfony/web-profiler-bundle": "8.0.*"
|
||||||
},
|
},
|
||||||
|
|||||||
100
composer.lock
generated
100
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "9c4e168c0540baf5d7d5d54040834d79",
|
"content-hash": "9c04091eea0e10c19713a1d882b04f91",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "api-platform/doctrine-common",
|
"name": "api-platform/doctrine-common",
|
||||||
@@ -11357,6 +11357,104 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-12-06T17:00:47+00:00"
|
"time": "2025-12-06T17:00:47+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/maker-bundle",
|
||||||
|
"version": "v1.65.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/maker-bundle.git",
|
||||||
|
"reference": "eba30452d212769c9a5bcf0716959fd8ba1e54e3"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/maker-bundle/zipball/eba30452d212769c9a5bcf0716959fd8ba1e54e3",
|
||||||
|
"reference": "eba30452d212769c9a5bcf0716959fd8ba1e54e3",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/inflector": "^2.0",
|
||||||
|
"nikic/php-parser": "^5.0",
|
||||||
|
"php": ">=8.1",
|
||||||
|
"symfony/config": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/console": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/dependency-injection": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/deprecation-contracts": "^2.2|^3",
|
||||||
|
"symfony/filesystem": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/finder": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/framework-bundle": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/http-kernel": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/process": "^6.4|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"doctrine/doctrine-bundle": "<2.10",
|
||||||
|
"doctrine/orm": "<2.15"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"composer/semver": "^3.0",
|
||||||
|
"doctrine/doctrine-bundle": "^2.5.0|^3.0.0",
|
||||||
|
"doctrine/orm": "^2.15|^3",
|
||||||
|
"doctrine/persistence": "^3.1|^4.0",
|
||||||
|
"symfony/http-client": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/phpunit-bridge": "^6.4.1|^7.0|^8.0",
|
||||||
|
"symfony/security-core": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/security-http": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/yaml": "^6.4|^7.0|^8.0",
|
||||||
|
"twig/twig": "^3.0|^4.x-dev"
|
||||||
|
},
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Bundle\\MakerBundle\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.",
|
||||||
|
"homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html",
|
||||||
|
"keywords": [
|
||||||
|
"code generator",
|
||||||
|
"dev",
|
||||||
|
"generator",
|
||||||
|
"scaffold",
|
||||||
|
"scaffolding"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/symfony/maker-bundle/issues",
|
||||||
|
"source": "https://github.com/symfony/maker-bundle/tree/v1.65.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-12-02T07:14:37+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v8.0.4",
|
"version": "v8.0.4",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle;
|
|||||||
use Malio\EdnotifBundle\EdnotifBundle;
|
use Malio\EdnotifBundle\EdnotifBundle;
|
||||||
use Nelmio\CorsBundle\NelmioCorsBundle;
|
use Nelmio\CorsBundle\NelmioCorsBundle;
|
||||||
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||||
|
use Symfony\Bundle\MakerBundle\MakerBundle;
|
||||||
use Symfony\Bundle\MonologBundle\MonologBundle;
|
use Symfony\Bundle\MonologBundle\MonologBundle;
|
||||||
use Symfony\Bundle\SecurityBundle\SecurityBundle;
|
use Symfony\Bundle\SecurityBundle\SecurityBundle;
|
||||||
use Symfony\Bundle\TwigBundle\TwigBundle;
|
use Symfony\Bundle\TwigBundle\TwigBundle;
|
||||||
@@ -28,4 +29,5 @@ return [
|
|||||||
EdnotifBundle::class => ['all' => true],
|
EdnotifBundle::class => ['all' => true],
|
||||||
WebProfilerBundle::class => ['dev' => true],
|
WebProfilerBundle::class => ['dev' => true],
|
||||||
DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
|
||||||
|
MakerBundle::class => ['dev' => true],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1503,7 +1503,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
|||||||
* validation_error_resource_class?: scalar|Param|null, // The class used to represent validation errors in the OpenAPI documentation. // Default: null
|
* validation_error_resource_class?: scalar|Param|null, // The class used to represent validation errors in the OpenAPI documentation. // Default: null
|
||||||
* },
|
* },
|
||||||
* maker?: bool|array{
|
* maker?: bool|array{
|
||||||
* enabled?: bool|Param, // Default: false
|
* enabled?: bool|Param, // Default: true
|
||||||
* },
|
* },
|
||||||
* exception_to_status?: array<string, int|Param>,
|
* exception_to_status?: array<string, int|Param>,
|
||||||
* formats?: array<string, array{ // Default: {"jsonld":{"mime_types":["application/ld+json"]}}
|
* formats?: array<string, array{ // Default: {"jsonld":{"mime_types":["application/ld+json"]}}
|
||||||
@@ -1778,6 +1778,11 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
|||||||
* intercept_redirects?: bool|Param, // Default: false
|
* intercept_redirects?: bool|Param, // Default: false
|
||||||
* excluded_ajax_paths?: scalar|Param|null, // Default: "^/((index|app(_[\\w]+)?)\\.php/)?_wdt"
|
* excluded_ajax_paths?: scalar|Param|null, // Default: "^/((index|app(_[\\w]+)?)\\.php/)?_wdt"
|
||||||
* }
|
* }
|
||||||
|
* @psalm-type MakerConfig = array{
|
||||||
|
* root_namespace?: scalar|Param|null, // Default: "App"
|
||||||
|
* generate_final_classes?: bool|Param, // Default: true
|
||||||
|
* generate_final_entities?: bool|Param, // Default: false
|
||||||
|
* }
|
||||||
* @psalm-type ConfigType = array{
|
* @psalm-type ConfigType = array{
|
||||||
* imports?: ImportsConfig,
|
* imports?: ImportsConfig,
|
||||||
* parameters?: ParametersConfig,
|
* parameters?: ParametersConfig,
|
||||||
@@ -1807,6 +1812,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
|
|||||||
* monolog?: MonologConfig,
|
* monolog?: MonologConfig,
|
||||||
* ednotif?: EdnotifConfig,
|
* ednotif?: EdnotifConfig,
|
||||||
* web_profiler?: WebProfilerConfig,
|
* web_profiler?: WebProfilerConfig,
|
||||||
|
* maker?: MakerConfig,
|
||||||
* },
|
* },
|
||||||
* "when@prod"?: array{
|
* "when@prod"?: array{
|
||||||
* imports?: ImportsConfig,
|
* imports?: ImportsConfig,
|
||||||
|
|||||||
@@ -7,3 +7,5 @@ POSTGRES_USER=root
|
|||||||
POSTGRES_PASSWORD=root
|
POSTGRES_PASSWORD=root
|
||||||
POSTGRES_PORT=5432
|
POSTGRES_PORT=5432
|
||||||
XDEBUG_CLIENT_HOST=host.docker.internal
|
XDEBUG_CLIENT_HOST=host.docker.internal
|
||||||
|
CURRENT_UID=1004
|
||||||
|
CURRENT_GID=1004
|
||||||
|
|||||||
203
frontend/components/reception/reception-bovine-received.vue
Normal file
203
frontend/components/reception/reception-bovine-received.vue
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
<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 {MERCHANDISE_TYPE_CODES, 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 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 toast = useToast()
|
||||||
|
const nuxtApp = useNuxtApp()
|
||||||
|
const i18n = nuxtApp.$i18n as { t: (key: string) => string } |
|
||||||
|
undefined
|
||||||
|
const t = (key: string) => (i18n?.t ? String(i18n.t(key)) : key)
|
||||||
|
const totalBovineQuantity = computed(() => {
|
||||||
|
const baseTotal = Object.values(bovineQuantities).reduce((sum, value) => {
|
||||||
|
const n = typeof value === 'number' ? value : 0
|
||||||
|
return sum + n
|
||||||
|
}, 0)
|
||||||
|
const other = typeof otherQuantity.value === 'number' ? otherQuantity.value : 0
|
||||||
|
return baseTotal + other
|
||||||
|
})
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const hasNegativeQuantity = computed(() => {
|
||||||
|
const anyNegativeInTypes =
|
||||||
|
Object.values(bovineQuantities).some((value) => {
|
||||||
|
return typeof value === 'number' && value < 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const otherNegative =
|
||||||
|
typeof otherQuantity.value === 'number' &&
|
||||||
|
otherQuantity.value < 0
|
||||||
|
|
||||||
|
return anyNegativeInTypes || otherNegative
|
||||||
|
})
|
||||||
|
async function goNext() {
|
||||||
|
if (!receptionStore.current || !receptionIri.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (hasNegativeQuantity.value) {
|
||||||
|
toast.error({
|
||||||
|
title: 'Erreur',
|
||||||
|
message: ("La quantité de bovins ne peut pas être négative.")
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Le 52 à vérifier
|
||||||
|
if (totalBovineQuantity.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,7 +142,8 @@ import type {DriverData} from '~/services/dto/driver-data'
|
|||||||
import {getDriverList} from '~/services/driver'
|
import {getDriverList} from '~/services/driver'
|
||||||
import type {VehicleData} from '~/services/dto/vehicle-data'
|
import type {VehicleData} from '~/services/dto/vehicle-data'
|
||||||
import {getVehicleList} from '~/services/vehicle'
|
import {getVehicleList} from '~/services/vehicle'
|
||||||
import {SUPLLIER_CODE} from "~/utils/constants";
|
import {RECEPTION_TYPE_CODES, SUPLLIER_CODE} from "~/utils/constants";
|
||||||
|
import {deleteReceptionBovine, getReceptionBovineList} from "~/services/reception-bovine";
|
||||||
|
|
||||||
type ReceptionFormData = {
|
type ReceptionFormData = {
|
||||||
licensePlate: string
|
licensePlate: string
|
||||||
@@ -221,6 +222,16 @@ const filteredVehicles = computed<VehicleData[]>(() => {
|
|||||||
(!form.truckId || String(vehicle.truck?.id) === form.truckId)
|
(!form.truckId || String(vehicle.truck?.id) === form.truckId)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
const selectedReceptionType = computed(() =>
|
||||||
|
receptionTypes.value.find((type) => String(type.id) === form.receptionTypeId) ?? null
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
// Hydrate le formulaire depuis la réception en cours
|
||||||
watch(
|
watch(
|
||||||
@@ -460,6 +471,9 @@ async function validate() {
|
|||||||
const normalizedTruckId = form.truckId.trim()
|
const normalizedTruckId = form.truckId.trim()
|
||||||
const normalizedCarrierId = form.carrierId.trim()
|
const normalizedCarrierId = form.carrierId.trim()
|
||||||
const normalizedDriverId = form.driverId.trim()
|
const normalizedDriverId = form.driverId.trim()
|
||||||
|
const previousTypeCode = receptionStore.current.receptionType?.code ?? null
|
||||||
|
const nextTypeCode = selectedReceptionType.value?.code ?? null
|
||||||
|
const receptionIri = `/api/receptions/${receptionStore.current.id}`
|
||||||
const receptionTypeIri = normalizedReceptionTypeId
|
const receptionTypeIri = normalizedReceptionTypeId
|
||||||
? `/api/reception_types/${normalizedReceptionTypeId}`
|
? `/api/reception_types/${normalizedReceptionTypeId}`
|
||||||
: null
|
: null
|
||||||
@@ -508,7 +522,12 @@ async function validate() {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
previousTypeCode === RECEPTION_TYPE_CODES.BOVINS &&
|
||||||
|
nextTypeCode === RECEPTION_TYPE_CODES.MERCHANDISES
|
||||||
|
) {
|
||||||
|
await clearReceptionBovines(receptionIri)
|
||||||
|
}
|
||||||
const nextStep = receptionStore.current.currentStep + 1
|
const nextStep = receptionStore.current.currentStep + 1
|
||||||
await receptionStore.updateReception(receptionStore.current.id, {
|
await receptionStore.updateReception(receptionStore.current.id, {
|
||||||
currentStep: nextStep,
|
currentStep: nextStep,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col items-center gap-16">
|
<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 -->
|
<!-- @TODO voir pour séparer dans un composant au moment de l'implémentation des Bovins -->
|
||||||
<div
|
<div
|
||||||
v-if="receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.MERCHANDISES"
|
v-if="receptionStore.current?.receptionType?.code === RECEPTION_TYPE_CODES.MERCHANDISES"
|
||||||
class="flex flex-col gap-16 items-center w-full">
|
class="flex flex-col gap-16 items-center w-full">
|
||||||
<h1 class="text-4xl uppercase font-bold">Sélectionner des marchandises réceptionnnées</h1>
|
<h1 class="text-4xl uppercase font-bold">Sélection des marchandises réceptionnnées</h1>
|
||||||
<UiSelect
|
<UiSelect
|
||||||
id="merchandise-type"
|
id="merchandise-type"
|
||||||
v-model="selectedMerchandiseTypeId"
|
v-model="selectedMerchandiseTypeId"
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
:options="merchandiseTypes.map((type) => ({ value: String(type.id), label: type.label }))"
|
:options="merchandiseTypes.map((type) => ({ value: String(type.id), label: type.label }))"
|
||||||
wrapper-class="w-[550px]"
|
wrapper-class="w-[550px]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="selectedMerchandiseTypeId && isAutres"
|
v-if="selectedMerchandiseTypeId && isAutres"
|
||||||
class="flex flex-col w-full max-w-[550px]"
|
class="flex flex-col w-full max-w-[550px]"
|
||||||
@@ -69,25 +68,27 @@
|
|||||||
<button
|
<button
|
||||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||||
@click="goNext"
|
@click="goNext"
|
||||||
>Peser</button>
|
>Peser
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref } from 'vue'
|
import {computed, onMounted, ref} from 'vue'
|
||||||
import { getBuildingList } from '~/services/building'
|
import {getBuildingList} from '~/services/building'
|
||||||
import { getMerchandiseTypeList } from '~/services/merchandise-type'
|
import {getMerchandiseTypeList} from '~/services/merchandise-type'
|
||||||
import type { MerchandiseTypeData } from '~/services/dto/merchandise-type-data'
|
import type {MerchandiseTypeData} from '~/services/dto/merchandise-type-data'
|
||||||
import type { BuildingData } from '~/services/dto/building-data'
|
import type {BuildingData} from '~/services/dto/building-data'
|
||||||
import type { PelletTypeData } from '~/services/dto/pellet-type-data'
|
import type {PelletTypeData} from '~/services/dto/pellet-type-data'
|
||||||
import { getPelletTypeList } from '~/services/pellet-type'
|
import {getPelletTypeList} from '~/services/pellet-type'
|
||||||
import {
|
import {
|
||||||
createReceptionPelletBuilding,
|
createReceptionPelletBuilding,
|
||||||
deleteReceptionPelletBuilding,
|
deleteReceptionPelletBuilding,
|
||||||
getReceptionPelletBuildingList
|
getReceptionPelletBuildingList
|
||||||
} from '~/services/reception-pellet-building'
|
} from '~/services/reception-pellet-building'
|
||||||
import { useReceptionStore } from '~/stores/reception'
|
import {useReceptionStore} from '~/stores/reception'
|
||||||
import { MERCHANDISE_TYPE_CODES, RECEPTION_TYPE_CODES } from '~/utils/constants'
|
import {MERCHANDISE_TYPE_CODES, RECEPTION_TYPE_CODES} from '~/utils/constants'
|
||||||
|
import ReceptionBovineReceived from "~/components/reception/reception-bovine-received.vue";
|
||||||
|
|
||||||
const receptionStore = useReceptionStore()
|
const receptionStore = useReceptionStore()
|
||||||
const merchandiseTypes = ref<MerchandiseTypeData[]>([])
|
const merchandiseTypes = ref<MerchandiseTypeData[]>([])
|
||||||
@@ -98,6 +99,31 @@ const selectedBuildingIds = ref<string[]>([])
|
|||||||
const selectedPelletBuildingIds = ref<Record<string, string[]>>({})
|
const selectedPelletBuildingIds = ref<Record<string, string[]>>({})
|
||||||
const merchandiseDetail = ref('')
|
const merchandiseDetail = ref('')
|
||||||
|
|
||||||
|
|
||||||
|
// Extrait l'ID d'une relation depuis un IRI ou un objet complet.
|
||||||
|
const getRelationId = (value: unknown): string | null => {
|
||||||
|
if (!value) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
const match = value.match(/\/(\d+)$/)
|
||||||
|
return match ? match[1] : null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'object' && 'id' in value) {
|
||||||
|
const record = value as { id?: number | string }
|
||||||
|
if (typeof record.id === 'number') {
|
||||||
|
return String(record.id)
|
||||||
|
}
|
||||||
|
if (typeof record.id === 'string') {
|
||||||
|
return record.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// Type de marchandise sélectionné dans le select
|
// Type de marchandise sélectionné dans le select
|
||||||
const selectedMerchandiseType = computed(() =>
|
const selectedMerchandiseType = computed(() =>
|
||||||
merchandiseTypes.value.find((type) => String(type.id) === selectedMerchandiseTypeId.value)
|
merchandiseTypes.value.find((type) => String(type.id) === selectedMerchandiseTypeId.value)
|
||||||
@@ -130,8 +156,12 @@ onMounted(async () => {
|
|||||||
const existingPelletSelections = receptionStore.current?.pelletBuildings ?? []
|
const existingPelletSelections = receptionStore.current?.pelletBuildings ?? []
|
||||||
const selectionMap: Record<string, string[]> = {}
|
const selectionMap: Record<string, string[]> = {}
|
||||||
for (const selection of existingPelletSelections) {
|
for (const selection of existingPelletSelections) {
|
||||||
const pelletTypeId = String(selection.pelletType.id)
|
// L'API peut renvoyer les relations comme IRI ou comme objets selon le contexte.
|
||||||
const buildingId = String(selection.building.id)
|
const pelletTypeId = getRelationId(selection.pelletType)
|
||||||
|
const buildingId = getRelationId(selection.building)
|
||||||
|
if (!pelletTypeId || !buildingId) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if (!selectionMap[pelletTypeId]) {
|
if (!selectionMap[pelletTypeId]) {
|
||||||
selectionMap[pelletTypeId] = []
|
selectionMap[pelletTypeId] = []
|
||||||
}
|
}
|
||||||
@@ -145,7 +175,6 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
selectedPelletBuildingIds.value = selectionMap
|
selectedPelletBuildingIds.value = selectionMap
|
||||||
})
|
})
|
||||||
|
|
||||||
// Enregistre les sélections et passe à l'étape suivante
|
// Enregistre les sélections et passe à l'étape suivante
|
||||||
async function goNext() {
|
async function goNext() {
|
||||||
if (!receptionStore.current) {
|
if (!receptionStore.current) {
|
||||||
@@ -163,6 +192,8 @@ async function goNext() {
|
|||||||
buildings: isGranule.value
|
buildings: isGranule.value
|
||||||
? []
|
? []
|
||||||
: selectedBuildingIds.value.map((id) => `/api/buildings/${id}`),
|
: selectedBuildingIds.value.map((id) => `/api/buildings/${id}`),
|
||||||
|
bovineDetail: null,
|
||||||
|
bovinesTypes: null,
|
||||||
currentStep: nextStep
|
currentStep: nextStep
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -180,20 +211,25 @@ async function clearPelletSelections(receptionIri: string) {
|
|||||||
await deleteReceptionPelletBuilding(selection.id)
|
await deleteReceptionPelletBuilding(selection.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronise les associations granulés/bâtiments avec l'état du formulaire
|
// Synchronise les associations granulés/bâtiments avec l'état du formulaire
|
||||||
async function syncPelletSelections(receptionIri: string) {
|
async function syncPelletSelections(receptionIri: string) {
|
||||||
const existing = await getReceptionPelletBuildingList(receptionIri)
|
const existing = await getReceptionPelletBuildingList(receptionIri)
|
||||||
const existingMap = new Map<string, number>()
|
const existingMap = new Map<string, number>()
|
||||||
for (const selection of existing) {
|
for (const selection of existing) {
|
||||||
const key = `${selection.pelletType.id}:${selection.building.id}`
|
// Construit la table de correspondance avec des IDs normalisés pour éviter les doublons.
|
||||||
|
const pelletTypeId = getRelationId(selection.pelletType)
|
||||||
|
const buildingId = getRelationId(selection.building)
|
||||||
|
if (!pelletTypeId || !buildingId) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const key = `${pelletTypeId}:${buildingId}`
|
||||||
existingMap.set(key, selection.id)
|
existingMap.set(key, selection.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const desiredEntries: Array<{ pelletTypeId: string; buildingId: string }> = []
|
const desiredEntries: Array<{ pelletTypeId: string; buildingId: string }> = []
|
||||||
for (const [pelletTypeId, buildingIds] of Object.entries(selectedPelletBuildingIds.value)) {
|
for (const [pelletTypeId, buildingIds] of Object.entries(selectedPelletBuildingIds.value)) {
|
||||||
for (const buildingId of buildingIds) {
|
for (const buildingId of buildingIds) {
|
||||||
desiredEntries.push({ pelletTypeId, buildingId })
|
desiredEntries.push({pelletTypeId, buildingId})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,14 +73,8 @@ const printReceipt = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ouvre l'onglet tout de suite pour éviter le blocage popup de Chrome
|
|
||||||
const previewWindow = window.open('', '_blank')
|
|
||||||
if (previewWindow) {
|
|
||||||
previewWindow.opener = null
|
|
||||||
}
|
|
||||||
|
|
||||||
await saveWeight()
|
await saveWeight()
|
||||||
await printPdf(`/receptions/${receptionStore.current.id}/receipt`, previewWindow)
|
await printPdf(`/receptions/${receptionStore.current.id}/receipt`)
|
||||||
|
|
||||||
// Laisse le temps a la boite de dialogue d'impression de s'ouvrir.
|
// Laisse le temps a la boite de dialogue d'impression de s'ouvrir.
|
||||||
await new Promise((resolve) => setTimeout(resolve, 600))
|
await new Promise((resolve) => setTimeout(resolve, 600))
|
||||||
@@ -98,6 +92,8 @@ const printReceipt = async () => {
|
|||||||
|
|
||||||
// Récupère le poids dès l'arrivée sur l'écran
|
// Récupère le poids dès l'arrivée sur l'écran
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchWeight()
|
if (false === displayWeight.value) {
|
||||||
|
fetchWeight()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
84
frontend/components/ui/UiNumberInput.vue
Normal file
84
frontend/components/ui/UiNumberInput.vue
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<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
|
||||||
|
]"
|
||||||
|
@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 = Number(target.value)
|
||||||
|
emit('update:modelValue', Number.isNaN(numeric) ? null : numeric)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -5,7 +5,7 @@ export const usePdfPrinter = () => {
|
|||||||
const receptionStore = useReceptionStore()
|
const receptionStore = useReceptionStore()
|
||||||
const currentReception = receptionStore.current
|
const currentReception = receptionStore.current
|
||||||
|
|
||||||
const printPdf = async (url: string, previewWindow?: Window | null): Promise<void> => {
|
const printPdf = async (url: string): Promise<void> => {
|
||||||
const blob = await api.getBlob(url);
|
const blob = await api.getBlob(url);
|
||||||
|
|
||||||
const pdfBlob = blob.type === 'application/pdf'
|
const pdfBlob = blob.type === 'application/pdf'
|
||||||
@@ -16,17 +16,14 @@ export const usePdfPrinter = () => {
|
|||||||
|
|
||||||
const filename = `${currentReception.identificationNumber}_${currentReception.supplier.name}_${currentReception.licensePlate}.pdf`;
|
const filename = `${currentReception.identificationNumber}_${currentReception.supplier.name}_${currentReception.licensePlate}.pdf`;
|
||||||
|
|
||||||
if (previewWindow) {
|
const a = document.createElement('a');
|
||||||
previewWindow.location.replace(blobUrl)
|
a.href = blobUrl;
|
||||||
}
|
a.download = filename;
|
||||||
|
a.style.display = 'none';
|
||||||
const a = document.createElement('a')
|
document.body.appendChild(a);
|
||||||
a.href = blobUrl
|
a.click();
|
||||||
a.download = filename
|
a.remove();
|
||||||
a.style.display = 'none'
|
// L'ouverture dans un nouvel onglet déclenche un 2e PDF sans le nom personnalisé.
|
||||||
document.body.appendChild(a)
|
|
||||||
a.click()
|
|
||||||
a.remove()
|
|
||||||
setTimeout(() => URL.revokeObjectURL(blobUrl), 60_000);
|
setTimeout(() => URL.revokeObjectURL(blobUrl), 60_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,20 @@
|
|||||||
"create": "Impossible d'enregistrer le dépôt 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."
|
"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": {
|
"supplier": {
|
||||||
"list": "Impossible de récupérer la liste des fournisseurs."
|
"list": "Impossible de récupérer la liste des fournisseurs."
|
||||||
},
|
},
|
||||||
"truck": {
|
"truck": {
|
||||||
"list": "Impossible de récupérer la liste des camions."
|
"list": "Impossible de récupérer la liste des camions."
|
||||||
},
|
},
|
||||||
|
"bovin": {
|
||||||
|
"list": "Impossible de récupérer la liste des races de bovins."
|
||||||
|
},
|
||||||
"carrier": {
|
"carrier": {
|
||||||
"list": "Impossible de récupérer la liste des transporteurs."
|
"list": "Impossible de récupérer la liste des transporteurs."
|
||||||
},
|
},
|
||||||
@@ -50,9 +58,6 @@
|
|||||||
"login": "Identifiants invalides.",
|
"login": "Identifiants invalides.",
|
||||||
"users": "Impossible de récupérer les utilisateurs.",
|
"users": "Impossible de récupérer les utilisateurs.",
|
||||||
"logout": "Impossible de se déconnecter."
|
"logout": "Impossible de se déconnecter."
|
||||||
},
|
|
||||||
"identificationBovin": {
|
|
||||||
"get": "Impossible de récupérer les informations du bovin"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
|
|||||||
@@ -28,15 +28,6 @@
|
|||||||
Reception
|
Reception
|
||||||
</a>
|
</a>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink to="/identification-bovin" custom v-slot="{ href, navigate, isActive }">
|
|
||||||
<a
|
|
||||||
:href="href"
|
|
||||||
@click="navigate"
|
|
||||||
:class="isIdentificationActive ? 'opacity-100' : 'opacity-50'"
|
|
||||||
>
|
|
||||||
Identification
|
|
||||||
</a>
|
|
||||||
</NuxtLink>
|
|
||||||
</nav>
|
</nav>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -59,7 +50,6 @@ import { useAuthStore } from '~/stores/auth'
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const auth = useAuthStore()
|
const auth = useAuthStore()
|
||||||
const isReceptionActive = computed(() => route.path.startsWith('/reception'))
|
const isReceptionActive = computed(() => route.path.startsWith('/reception'))
|
||||||
const isIdentificationActive = computed(() => route.path.startsWith('/identification-bovin'))
|
|
||||||
|
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="flex justify-between">
|
|
||||||
<h1 class="font-bold text-4xl uppercase">Passeport du bovin</h1>
|
|
||||||
<p v-if="bovinData">{{ bovinData.presencePeriod }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="overflow-x-auto mt-12" v-if="bovinData">
|
|
||||||
<table class="w-full border-collapse border border-black text-sm">
|
|
||||||
<tr>
|
|
||||||
<th
|
|
||||||
rowspan="2"
|
|
||||||
class="w-10 border border-black p-0 align-middle"
|
|
||||||
>
|
|
||||||
<div class="flex h-full w-full items-center justify-center">
|
|
||||||
<span class="-rotate-90 whitespace-nowrap font-semibold tracking-widest">
|
|
||||||
VEAU
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">N° de travail</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">Sexe</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">Code Race</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">Code pays</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">Type de racial</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">Date de naissance</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">{{ bovinData.workNumber }}</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">{{ bovinData.sex }}</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">{{ bovinData.breedType }}</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">FR {{ bovinData.numeroNational }}</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">???</th>
|
|
||||||
<th class="border border-black px-4 py-3 text-center font-semibold">{{ bovinData.birthDate }}</th>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import {getBovinData} from "~/services/identification-bovin";
|
|
||||||
|
|
||||||
const bovinData = ref<IdentificationBovinData|null>()
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
bovinData.value = await getBovinData('7979580026');
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
@@ -16,7 +16,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<ReceptionForm v-if="!storeReception || storeReception.currentStep === 0"/>
|
<ReceptionForm v-if="!storeReception || storeReception.currentStep === 0"/>
|
||||||
<ReceptionWeight v-if="storeReception?.currentStep === 1" mode="gross"/>
|
<ReceptionWeight v-if="storeReception?.currentStep === 1" mode="gross"/>
|
||||||
<ReceptionProductReceived v-if="storeReception?.currentStep === 2"/>
|
<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"/>
|
||||||
<ReceptionWeight v-if="storeReception?.currentStep !== null && storeReception?.currentStep >= 3" mode="tare"/>
|
<ReceptionWeight v-if="storeReception?.currentStep !== null && storeReception?.currentStep >= 3" mode="tare"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -25,6 +30,7 @@
|
|||||||
import {useReceptionStore} from '~/stores/reception'
|
import {useReceptionStore} from '~/stores/reception'
|
||||||
import {storeToRefs} from 'pinia'
|
import {storeToRefs} from 'pinia'
|
||||||
import {RECEPTION_STEP_LABELS} from '~/constants/steps'
|
import {RECEPTION_STEP_LABELS} from '~/constants/steps'
|
||||||
|
import {RECEPTION_TYPE_CODES} from "~/utils/constants";
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|||||||
23
frontend/services/bovine-type.ts
Normal file
23
frontend/services/bovine-type.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
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 []
|
||||||
|
}
|
||||||
5
frontend/services/dto/bovine-type-data.ts
Normal file
5
frontend/services/dto/bovine-type-data.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export interface BovineTypeData{
|
||||||
|
id: number
|
||||||
|
label: string
|
||||||
|
code: string
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
interface IdentificationBovinData {
|
|
||||||
numeroNational: string,
|
|
||||||
sex: string | null,
|
|
||||||
breedType: string | null,
|
|
||||||
workNumber: string | null,
|
|
||||||
birthDate: string | null,
|
|
||||||
birthDateCompletenessFlag: string | null,
|
|
||||||
isFilie: boolean | null,
|
|
||||||
motherNationalNumber: string | null,
|
|
||||||
motherBreedType: string | null,
|
|
||||||
fatherNationalNumber: string | null,
|
|
||||||
fatherBreedType: string | null,
|
|
||||||
birthExploitationNumber: string | null,
|
|
||||||
presencePeriod: PresencePeriod[]
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PresencePeriod {
|
|
||||||
entryDate: string | null,
|
|
||||||
entryCause: string | null,
|
|
||||||
exitDate: string | null,
|
|
||||||
exitCause: string | null
|
|
||||||
}
|
|
||||||
8
frontend/services/dto/reception-bovine-data.ts
Normal file
8
frontend/services/dto/reception-bovine-data.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||||
|
|
||||||
|
export interface ReceptionBovineTypeData{
|
||||||
|
id: number
|
||||||
|
quantity : number
|
||||||
|
reception?: string
|
||||||
|
bovineType: BovineTypeData
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import type { AddressData } from '~/services/dto/address-data'
|
|||||||
import type { TruckData } from '~/services/dto/truck-data'
|
import type { TruckData } from '~/services/dto/truck-data'
|
||||||
import type { CarrierData } from '~/services/dto/carrier-data'
|
import type { CarrierData } from '~/services/dto/carrier-data'
|
||||||
import type { DriverData } from '~/services/dto/driver-data'
|
import type { DriverData } from '~/services/dto/driver-data'
|
||||||
|
import type {BovineTypeData} from "~/services/dto/bovine-type-data";
|
||||||
|
|
||||||
export interface ReceptionData {
|
export interface ReceptionData {
|
||||||
id: number
|
id: number
|
||||||
@@ -20,7 +21,9 @@ export interface ReceptionData {
|
|||||||
receptionType?: ReceptionTypeData | null
|
receptionType?: ReceptionTypeData | null
|
||||||
merchandiseType?: MerchandiseTypeData | null
|
merchandiseType?: MerchandiseTypeData | null
|
||||||
merchandiseDetail?: string | null
|
merchandiseDetail?: string | null
|
||||||
|
bovineDetail?: string | null
|
||||||
buildings?: BuildingData[] | null
|
buildings?: BuildingData[] | null
|
||||||
|
bovinesTypes?: BovineTypeData[] | null
|
||||||
pelletBuildings?: ReceptionPelletBuildingData[] | null
|
pelletBuildings?: ReceptionPelletBuildingData[] | null
|
||||||
user?: UserData | null
|
user?: UserData | null
|
||||||
supplier?: SupplierData | null
|
supplier?: SupplierData | null
|
||||||
@@ -46,7 +49,9 @@ export type ReceptionPayload = {
|
|||||||
receptionType?: string | null
|
receptionType?: string | null
|
||||||
merchandiseType?: string | null
|
merchandiseType?: string | null
|
||||||
merchandiseDetail?: string | null
|
merchandiseDetail?: string | null
|
||||||
|
bovineDetail?: string | null
|
||||||
buildings?: string[] | null
|
buildings?: string[] | null
|
||||||
|
bovinesTypes?: string[] | null
|
||||||
user?: string | null
|
user?: string | null
|
||||||
supplier?: string | null
|
supplier?: string | null
|
||||||
address?: string | null
|
address?: string | null
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
import { useApi } from '~/composables/useApi'
|
|
||||||
|
|
||||||
export type BovinDataResponse =
|
|
||||||
| IdentificationBovinData
|
|
||||||
| { 'hydra:member'?: IdentificationBovinData }
|
|
||||||
|
|
||||||
export async function getBovinData(
|
|
||||||
nationalNumber: string
|
|
||||||
): Promise<IdentificationBovinData | null> {
|
|
||||||
const api = useApi()
|
|
||||||
const response = await api.get<BovinDataResponse>(
|
|
||||||
`bovins/${nationalNumber}/identification`,
|
|
||||||
{},
|
|
||||||
{ toastErrorKey: 'errors.building.list' }
|
|
||||||
)
|
|
||||||
|
|
||||||
if (response && typeof response === 'object') {
|
|
||||||
// direct item
|
|
||||||
if (!('hydra:member' in response)) return response as IdentificationBovinData
|
|
||||||
// hydra format
|
|
||||||
if (response['hydra:member']) return response['hydra:member']
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
59
frontend/services/reception-bovine.ts
Normal file
59
frontend/services/reception-bovine.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
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'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
export const RECEPTION_TYPE_CODES = {
|
export const RECEPTION_TYPE_CODES = {
|
||||||
MERCHANDISES: 'MARCHANDISES'
|
MERCHANDISES: 'MARCHANDISES',
|
||||||
|
BOVINS: 'BOVINS'
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export const MERCHANDISE_TYPE_CODES = {
|
export const MERCHANDISE_TYPE_CODES = {
|
||||||
|
|||||||
22
makefile
22
makefile
@@ -7,6 +7,9 @@ ENV_FILE := $(if $(wildcard $(ENV_LOCAL)),$(ENV_LOCAL),$(ENV_DEFAULT))
|
|||||||
include $(ENV_DEFAULT)
|
include $(ENV_DEFAULT)
|
||||||
-include $(ENV_LOCAL)
|
-include $(ENV_LOCAL)
|
||||||
|
|
||||||
|
HOST_UID := $(if $(SUDO_UID),$(SUDO_UID),$(shell id -u))
|
||||||
|
HOST_GID := $(if $(SUDO_GID),$(SUDO_GID),$(shell id -g))
|
||||||
|
|
||||||
PHP_CONTAINER = php-$(DOCKER_APP_NAME)-fpm
|
PHP_CONTAINER = php-$(DOCKER_APP_NAME)-fpm
|
||||||
SYMFONY_CONSOLE = $(EXEC_PHP) php bin/console
|
SYMFONY_CONSOLE = $(EXEC_PHP) php bin/console
|
||||||
|
|
||||||
@@ -24,13 +27,13 @@ FILES =
|
|||||||
|
|
||||||
env-init:
|
env-init:
|
||||||
@mkdir -p docker
|
@mkdir -p docker
|
||||||
@cp --update=none $(ENV_DEFAULT) $(ENV_LOCAL)
|
@cp -n $(ENV_DEFAULT) $(ENV_LOCAL)
|
||||||
|
|
||||||
# Lance le container
|
# Lance le container
|
||||||
start: env-init
|
start: env-init
|
||||||
@echo "**** START CONTAINERS ****"
|
@echo "**** START CONTAINERS ****"
|
||||||
@cp --update=none docker/.env.docker docker/.env.docker.local
|
@cp -n docker/.env.docker docker/.env.docker.local
|
||||||
CURRENT_UID=$(shell id -u) CURRENT_GID=$(shell id -g) $(DOCKER_COMPOSE) up -d
|
CURRENT_UID=$(HOST_UID) CURRENT_GID=$(HOST_GID) $(DOCKER_COMPOSE) up -d
|
||||||
|
|
||||||
# Éteint le container
|
# Éteint le container
|
||||||
stop:
|
stop:
|
||||||
@@ -38,7 +41,7 @@ stop:
|
|||||||
|
|
||||||
restart: env-init
|
restart: env-init
|
||||||
$(DOCKER_COMPOSE) down
|
$(DOCKER_COMPOSE) down
|
||||||
CURRENT_UID=$(shell id -u) CURRENT_GID=$(shell id -g) $(DOCKER_COMPOSE) up -d
|
CURRENT_UID=$(HOST_UID) CURRENT_GID=$(HOST_GID) $(DOCKER_COMPOSE) up -d
|
||||||
|
|
||||||
install: copy-git-hook composer-install cache-clear node-use build-nuxtJS migration-migrate
|
install: copy-git-hook composer-install cache-clear node-use build-nuxtJS migration-migrate
|
||||||
|
|
||||||
@@ -57,9 +60,8 @@ dev-nuxt:
|
|||||||
$(EXEC_PHP) sh -c "cd frontend && npm run dev"
|
$(EXEC_PHP) sh -c "cd frontend && npm run dev"
|
||||||
|
|
||||||
delete_built_dir:
|
delete_built_dir:
|
||||||
CURRENT_UID=$(shell id -u) CURRENT_GID=$(shell id -g) $(DOCKER_COMPOSE) up -d
|
rm -rf vendor/
|
||||||
$(DOCKER) exec -u root $(PHP_CONTAINER) rm -rf vendor/
|
rm -rf frontend/node_modules
|
||||||
$(DOCKER) exec -u root $(PHP_CONTAINER) rm -rf frontend/node_modules
|
|
||||||
|
|
||||||
remove_orphans:
|
remove_orphans:
|
||||||
$(DOCKER_COMPOSE) kill
|
$(DOCKER_COMPOSE) kill
|
||||||
@@ -69,12 +71,12 @@ build-without-cache:
|
|||||||
$(DOCKER_COMPOSE) build \
|
$(DOCKER_COMPOSE) build \
|
||||||
--build-arg="DOCKER_PHP_VERSION=$(DOCKER_PHP_VERSION)" \
|
--build-arg="DOCKER_PHP_VERSION=$(DOCKER_PHP_VERSION)" \
|
||||||
--build-arg="DOCKER_NODE_VERSION=$(DOCKER_NODE_VERSION)" \
|
--build-arg="DOCKER_NODE_VERSION=$(DOCKER_NODE_VERSION)" \
|
||||||
--build-arg="CURRENT_UID=$(shell id -u)" \
|
--build-arg="CURRENT_UID=$(HOST_UID)" \
|
||||||
--build-arg="CURRENT_GID=$(shell id -g)" \
|
--build-arg="CURRENT_GID=$(HOST_GID)" \
|
||||||
--no-cache
|
--no-cache
|
||||||
|
|
||||||
migration-migrate:
|
migration-migrate:
|
||||||
$(SYMFONY_CONSOLE) doctrine:migrations:migrate --no-interaction
|
$(SYMFONY_CONSOLE) --no-interaction doctrine:migrations:migrate --allow-no-migration
|
||||||
|
|
||||||
fixtures:
|
fixtures:
|
||||||
$(SYMFONY_CONSOLE) doctrine:fixtures:load
|
$(SYMFONY_CONSOLE) doctrine:fixtures:load
|
||||||
|
|||||||
96
migrations/Version20260203123000.php
Normal file
96
migrations/Version20260203123000.php
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20260203123000 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Normalize index and constraint names to match current Doctrine naming strategy.';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER INDEX idx_1b80e4864c3c5e0a RENAME TO IDX_1B80E48621DFC797');
|
||||||
|
$this->addSql('ALTER INDEX idx_1b80e4868bebb4b RENAME TO IDX_1B80E486C6957CCE');
|
||||||
|
|
||||||
|
$this->addSql('ALTER TABLE supplier_address DROP CONSTRAINT fk_3dce3c746f9b8a0');
|
||||||
|
$this->addSql('ALTER TABLE supplier_address DROP CONSTRAINT fk_3dce3c74f2c1d6a8');
|
||||||
|
$this->addSql('ALTER TABLE supplier_address ADD CONSTRAINT FK_8C2B1B9E2ADD6D8C FOREIGN KEY (supplier_id) REFERENCES supplier (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE supplier_address ADD CONSTRAINT FK_8C2B1B9EF5B7AF75 FOREIGN KEY (address_id) REFERENCES address (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER INDEX idx_3dce3c74f2c1d6a8 RENAME TO IDX_8C2B1B9E2ADD6D8C');
|
||||||
|
$this->addSql('ALTER INDEX idx_3dce3c746f9b8a0 RENAME TO IDX_8C2B1B9EF5B7AF75');
|
||||||
|
|
||||||
|
$this->addSql('DROP INDEX uniq_8d93d649f85e0677');
|
||||||
|
$this->addSql('DROP INDEX uniq_user_username');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_327C5DE7F85E0677 ON "user" (username)');
|
||||||
|
|
||||||
|
$this->addSql('ALTER INDEX idx_14b3bc5f4c3c5e0a RENAME TO IDX_11667CD921DFC797');
|
||||||
|
|
||||||
|
$this->addSql('ALTER INDEX idx_5df3aa933e4a2e34 RENAME TO IDX_5B59B8827C14DF52');
|
||||||
|
$this->addSql('ALTER INDEX idx_5df3aa93955258d RENAME TO IDX_5B59B882113969D3');
|
||||||
|
$this->addSql('ALTER INDEX idx_5df3aa934d2a7e12 RENAME TO IDX_5B59B8824D2A7E12');
|
||||||
|
|
||||||
|
$this->addSql('ALTER INDEX uniq_reception_identification_number RENAME TO UNIQ_50D6852F347639A5');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e37bd5b5d RENAME TO IDX_50D6852FB708E8B8');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e3bcaaa7c0 RENAME TO IDX_50D6852F928E8BF2');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e3a76ed395 RENAME TO IDX_50D6852FA76ED395');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e32add6e01 RENAME TO IDX_50D6852F2ADD6D8C');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e3f5b7af75 RENAME TO IDX_50D6852FF5B7AF75');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e3f7d15b1a RENAME TO IDX_50D6852FC6957CCE');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e34c3c5e0a RENAME TO IDX_50D6852F21DFC797');
|
||||||
|
$this->addSql('ALTER INDEX idx_83dc02e3f24c741b RENAME TO IDX_50D6852FC3423909');
|
||||||
|
|
||||||
|
$this->addSql('ALTER TABLE reception_building DROP CONSTRAINT fk_46e7f9f24d2a7e12');
|
||||||
|
$this->addSql('ALTER TABLE reception_building DROP CONSTRAINT fk_46e7f9f23e4a2e34');
|
||||||
|
$this->addSql('ALTER TABLE reception_building ADD CONSTRAINT FK_4DA1DCF07C14DF52 FOREIGN KEY (reception_id) REFERENCES reception (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE reception_building ADD CONSTRAINT FK_4DA1DCF04D2A7E12 FOREIGN KEY (building_id) REFERENCES building (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER INDEX idx_46e7f9f23e4a2e34 RENAME TO IDX_4DA1DCF07C14DF52');
|
||||||
|
$this->addSql('ALTER INDEX idx_46e7f9f24d2a7e12 RENAME TO IDX_4DA1DCF04D2A7E12');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER INDEX IDX_1B80E48621DFC797 RENAME TO idx_1b80e4864c3c5e0a');
|
||||||
|
$this->addSql('ALTER INDEX IDX_1B80E486C6957CCE RENAME TO idx_1b80e4868bebb4b');
|
||||||
|
|
||||||
|
$this->addSql('ALTER TABLE supplier_address DROP CONSTRAINT FK_8C2B1B9E2ADD6D8C');
|
||||||
|
$this->addSql('ALTER TABLE supplier_address DROP CONSTRAINT FK_8C2B1B9EF5B7AF75');
|
||||||
|
$this->addSql('ALTER TABLE supplier_address ADD CONSTRAINT fk_3dce3c746f9b8a0 FOREIGN KEY (address_id) REFERENCES address (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE supplier_address ADD CONSTRAINT fk_3dce3c74f2c1d6a8 FOREIGN KEY (supplier_id) REFERENCES supplier (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER INDEX IDX_8C2B1B9E2ADD6D8C RENAME TO idx_3dce3c74f2c1d6a8');
|
||||||
|
$this->addSql('ALTER INDEX IDX_8C2B1B9EF5B7AF75 RENAME TO idx_3dce3c746f9b8a0');
|
||||||
|
|
||||||
|
$this->addSql('DROP INDEX UNIQ_327C5DE7F85E0677');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX uniq_8d93d649f85e0677 ON "user" (username)');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX uniq_user_username ON "user" (username)');
|
||||||
|
|
||||||
|
$this->addSql('ALTER INDEX IDX_11667CD921DFC797 RENAME TO idx_14b3bc5f4c3c5e0a');
|
||||||
|
|
||||||
|
$this->addSql('ALTER INDEX IDX_5B59B8827C14DF52 RENAME TO idx_5df3aa933e4a2e34');
|
||||||
|
$this->addSql('ALTER INDEX IDX_5B59B882113969D3 RENAME TO idx_5df3aa93955258d');
|
||||||
|
$this->addSql('ALTER INDEX IDX_5B59B8824D2A7E12 RENAME TO idx_5df3aa934d2a7e12');
|
||||||
|
|
||||||
|
$this->addSql('ALTER INDEX UNIQ_50D6852F347639A5 RENAME TO uniq_reception_identification_number');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852FB708E8B8 RENAME TO idx_83dc02e37bd5b5d');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852F928E8BF2 RENAME TO idx_83dc02e3bcaaa7c0');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852FA76ED395 RENAME TO idx_83dc02e3a76ed395');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852F2ADD6D8C RENAME TO idx_83dc02e32add6e01');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852FF5B7AF75 RENAME TO idx_83dc02e3f5b7af75');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852FC6957CCE RENAME TO idx_83dc02e3f7d15b1a');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852F21DFC797 RENAME TO idx_83dc02e34c3c5e0a');
|
||||||
|
$this->addSql('ALTER INDEX IDX_50D6852FC3423909 RENAME TO idx_83dc02e3f24c741b');
|
||||||
|
|
||||||
|
$this->addSql('ALTER TABLE reception_building DROP CONSTRAINT FK_4DA1DCF07C14DF52');
|
||||||
|
$this->addSql('ALTER TABLE reception_building DROP CONSTRAINT FK_4DA1DCF04D2A7E12');
|
||||||
|
$this->addSql('ALTER TABLE reception_building ADD CONSTRAINT fk_46e7f9f23e4a2e34 FOREIGN KEY (reception_id) REFERENCES reception (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE reception_building ADD CONSTRAINT fk_46e7f9f24d2a7e12 FOREIGN KEY (building_id) REFERENCES building (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER INDEX IDX_4DA1DCF07C14DF52 RENAME TO idx_46e7f9f23e4a2e34');
|
||||||
|
$this->addSql('ALTER INDEX IDX_4DA1DCF04D2A7E12 RENAME TO idx_46e7f9f24d2a7e12');
|
||||||
|
}
|
||||||
|
}
|
||||||
39
migrations/Version20260203123833.php
Normal file
39
migrations/Version20260203123833.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?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');
|
||||||
|
}
|
||||||
|
}
|
||||||
33
migrations/Version20260204141406.php
Normal file
33
migrations/Version20260204141406.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?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');
|
||||||
|
}
|
||||||
|
}
|
||||||
31
migrations/Version20260205070819.php
Normal file
31
migrations/Version20260205070819.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,8 +15,7 @@ use App\State\BovinIdentificationProvider;
|
|||||||
uriTemplate: '/bovins/{numeroNational}/identification',
|
uriTemplate: '/bovins/{numeroNational}/identification',
|
||||||
provider: BovinIdentificationProvider::class
|
provider: BovinIdentificationProvider::class
|
||||||
),
|
),
|
||||||
],
|
]
|
||||||
security: "is_granted('ROLE_USER')",
|
|
||||||
)]
|
)]
|
||||||
final class BovinIdentification
|
final class BovinIdentification
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
|||||||
)]
|
)]
|
||||||
class SeedCommand extends Command
|
class SeedCommand extends Command
|
||||||
{
|
{
|
||||||
|
private int $created = 0;
|
||||||
|
private int $updated = 0;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly EntityManagerInterface $entityManager
|
private readonly EntityManagerInterface $entityManager
|
||||||
) {
|
) {
|
||||||
@@ -37,55 +40,32 @@ class SeedCommand extends Command
|
|||||||
{
|
{
|
||||||
$io = new SymfonyStyle($input, $output);
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
$created = 0;
|
$this->created = 0;
|
||||||
$updated = 0;
|
$this->updated = 0;
|
||||||
|
|
||||||
$truckRepo = $this->entityManager->getRepository(Truck::class);
|
$trucks = $this->seedTrucks();
|
||||||
$carrierRepo = $this->entityManager->getRepository(Carrier::class);
|
$carriers = $this->seedCarriers();
|
||||||
$driverRepo = $this->entityManager->getRepository(Driver::class);
|
$this->seedDriversAndVehicles($carriers['liot'] ?? null, $trucks['citerne'] ?? null, $trucks['porteur'] ?? null, $io);
|
||||||
$vehicleRepo = $this->entityManager->getRepository(Vehicle::class);
|
$this->seedMerchandiseTypes();
|
||||||
$merchandiseTypeRepo = $this->entityManager->getRepository(MerchandiseType::class);
|
$this->seedPelletTypes();
|
||||||
$pelletTypeRepo = $this->entityManager->getRepository(PelletType::class);
|
$this->seedBuildings();
|
||||||
$buildingRepo = $this->entityManager->getRepository(Building::class);
|
$this->seedReceptionTypes();
|
||||||
$receptionTypeRepo = $this->entityManager->getRepository(ReceptionType::class);
|
$this->seedSuppliers();
|
||||||
$addressRepo = $this->entityManager->getRepository(Address::class);
|
|
||||||
$supplierRepo = $this->entityManager->getRepository(Supplier::class);
|
|
||||||
|
|
||||||
$upsertByCode = function (string $entityClass, string $code, callable $apply) use (&$created, &$updated) {
|
$this->entityManager->flush();
|
||||||
$repo = $this->entityManager->getRepository($entityClass);
|
|
||||||
$entity = $repo->findOneBy(['code' => $code]);
|
|
||||||
if (!$entity) {
|
|
||||||
$entity = new $entityClass();
|
|
||||||
++$created;
|
|
||||||
} else {
|
|
||||||
++$updated;
|
|
||||||
}
|
|
||||||
$apply($entity);
|
|
||||||
$this->entityManager->persist($entity);
|
|
||||||
|
|
||||||
return $entity;
|
$io->success(sprintf('Seed completed: %d created, %d updated.', $this->created, $this->updated));
|
||||||
};
|
|
||||||
|
|
||||||
$upsertByName = function (string $entityClass, string $name, callable $apply) use (&$created, &$updated) {
|
return Command::SUCCESS;
|
||||||
$repo = $this->entityManager->getRepository($entityClass);
|
}
|
||||||
$entity = $repo->findOneBy(['name' => $name]);
|
|
||||||
if (!$entity) {
|
|
||||||
$entity = new $entityClass();
|
|
||||||
++$created;
|
|
||||||
} else {
|
|
||||||
++$updated;
|
|
||||||
}
|
|
||||||
$apply($entity);
|
|
||||||
$this->entityManager->persist($entity);
|
|
||||||
|
|
||||||
return $entity;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private function seedTrucks(): array
|
||||||
|
{
|
||||||
$trucks = ['Citerne', 'Porteur'];
|
$trucks = ['Citerne', 'Porteur'];
|
||||||
$citerne = null;
|
$citerne = null;
|
||||||
$porteur = null;
|
$porteur = null;
|
||||||
foreach ($trucks as $name) {
|
foreach ($trucks as $name) {
|
||||||
$truck = $upsertByName(Truck::class, $name, static fn (Truck $truck) => $truck->setName($name));
|
$truck = $this->upsertByName(Truck::class, $name, static fn (Truck $truck) => $truck->setName($name));
|
||||||
if ('Citerne' === $name) {
|
if ('Citerne' === $name) {
|
||||||
$citerne = $truck;
|
$citerne = $truck;
|
||||||
}
|
}
|
||||||
@@ -94,13 +74,21 @@ class SeedCommand extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'citerne' => $citerne,
|
||||||
|
'porteur' => $porteur,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function seedCarriers(): array
|
||||||
|
{
|
||||||
$carriers = [
|
$carriers = [
|
||||||
['name' => 'LIOT', 'code' => 'LIOT'],
|
['name' => 'LIOT', 'code' => 'LIOT'],
|
||||||
['name' => 'LUI-MEME', 'code' => 'LUI-MEME'],
|
['name' => 'LUI-MEME', 'code' => 'LUI-MEME'],
|
||||||
];
|
];
|
||||||
$liot = null;
|
$liot = null;
|
||||||
foreach ($carriers as $carrierData) {
|
foreach ($carriers as $carrierData) {
|
||||||
$carrier = $upsertByCode(Carrier::class, $carrierData['code'], static function (Carrier $carrier) use ($carrierData) {
|
$carrier = $this->upsertByCode(Carrier::class, $carrierData['code'], static function (Carrier $carrier) use ($carrierData) {
|
||||||
$carrier
|
$carrier
|
||||||
->setName($carrierData['name'])
|
->setName($carrierData['name'])
|
||||||
->setCode($carrierData['code'])
|
->setCode($carrierData['code'])
|
||||||
@@ -111,63 +99,81 @@ class SeedCommand extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($liot && $citerne && $porteur) {
|
return [
|
||||||
$drivers = ['Eddy', 'Jean-Christophe', 'Etienne', 'Hersand'];
|
'liot' => $liot,
|
||||||
foreach ($drivers as $name) {
|
];
|
||||||
$driver = $driverRepo->findOneBy(['name' => $name, 'carrier' => $liot]);
|
}
|
||||||
if (!$driver) {
|
|
||||||
$driver = new Driver();
|
|
||||||
++$created;
|
|
||||||
} else {
|
|
||||||
++$updated;
|
|
||||||
}
|
|
||||||
$driver
|
|
||||||
->setName($name)
|
|
||||||
->setCarrier($liot)
|
|
||||||
;
|
|
||||||
$this->entityManager->persist($driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
$vehicles = [
|
private function seedDriversAndVehicles(?Carrier $liot, ?Truck $citerne, ?Truck $porteur, SymfonyStyle $io): void
|
||||||
['plate' => 'GH-684-VZ', 'truck' => $citerne],
|
{
|
||||||
['plate' => 'FW-363-EC', 'truck' => $porteur],
|
if (!$liot || !$citerne || !$porteur) {
|
||||||
['plate' => 'FW-370-EC', 'truck' => $porteur],
|
|
||||||
['plate' => 'FW-375-EC', 'truck' => $porteur],
|
|
||||||
['plate' => 'FY-952-HS', 'truck' => $porteur],
|
|
||||||
];
|
|
||||||
foreach ($vehicles as $vehicleData) {
|
|
||||||
$vehicle = $vehicleRepo->findOneBy(['plate' => $vehicleData['plate']]);
|
|
||||||
if (!$vehicle) {
|
|
||||||
$vehicle = new Vehicle();
|
|
||||||
++$created;
|
|
||||||
} else {
|
|
||||||
++$updated;
|
|
||||||
}
|
|
||||||
$vehicle
|
|
||||||
->setPlate($vehicleData['plate'])
|
|
||||||
->setCarrier($liot)
|
|
||||||
->setTruck($vehicleData['truck'])
|
|
||||||
;
|
|
||||||
$this->entityManager->persist($vehicle);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$io->warning('Transport data not fully available; drivers/vehicles skipped.');
|
$io->warning('Transport data not fully available; drivers/vehicles skipped.');
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$driverRepo = $this->entityManager->getRepository(Driver::class);
|
||||||
|
$vehicleRepo = $this->entityManager->getRepository(Vehicle::class);
|
||||||
|
|
||||||
|
$drivers = ['Eddy', 'Jean-Christophe', 'Etienne', 'Hersand'];
|
||||||
|
foreach ($drivers as $name) {
|
||||||
|
$driver = $driverRepo->findOneBy(['name' => $name, 'carrier' => $liot]);
|
||||||
|
if (!$driver) {
|
||||||
|
$driver = new Driver();
|
||||||
|
++$this->created;
|
||||||
|
} else {
|
||||||
|
++$this->updated;
|
||||||
|
}
|
||||||
|
$driver
|
||||||
|
->setName($name)
|
||||||
|
->setCarrier($liot)
|
||||||
|
;
|
||||||
|
$this->entityManager->persist($driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
$vehicles = [
|
||||||
|
['plate' => 'GH-684-VZ', 'truck' => $citerne],
|
||||||
|
['plate' => 'FW-363-EC', 'truck' => $porteur],
|
||||||
|
['plate' => 'FW-370-EC', 'truck' => $porteur],
|
||||||
|
['plate' => 'FW-375-EC', 'truck' => $porteur],
|
||||||
|
['plate' => 'FY-952-HS', 'truck' => $porteur],
|
||||||
|
];
|
||||||
|
foreach ($vehicles as $vehicleData) {
|
||||||
|
$vehicle = $vehicleRepo->findOneBy(['plate' => $vehicleData['plate']]);
|
||||||
|
if (!$vehicle) {
|
||||||
|
$vehicle = new Vehicle();
|
||||||
|
++$this->created;
|
||||||
|
} else {
|
||||||
|
++$this->updated;
|
||||||
|
}
|
||||||
|
$vehicle
|
||||||
|
->setPlate($vehicleData['plate'])
|
||||||
|
->setCarrier($liot)
|
||||||
|
->setTruck($vehicleData['truck'])
|
||||||
|
;
|
||||||
|
$this->entityManager->persist($vehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function seedMerchandiseTypes(): void
|
||||||
|
{
|
||||||
$merchandiseTypes = [
|
$merchandiseTypes = [
|
||||||
['label' => 'Foin', 'code' => 'FOIN'],
|
['label' => 'Foin', 'code' => 'FOIN'],
|
||||||
['label' => 'Paille', 'code' => 'PAILLE'],
|
['label' => 'Paille', 'code' => 'PAILLE'],
|
||||||
['label' => 'Granule', 'code' => 'GRANULE'],
|
['label' => 'Granule', 'code' => 'GRANULE'],
|
||||||
];
|
];
|
||||||
foreach ($merchandiseTypes as $type) {
|
foreach ($merchandiseTypes as $type) {
|
||||||
$upsertByCode(MerchandiseType::class, $type['code'], static function (MerchandiseType $entity) use ($type) {
|
$this->upsertByCode(MerchandiseType::class, $type['code'], static function (MerchandiseType $entity) use ($type) {
|
||||||
$entity
|
$entity
|
||||||
->setLabel($type['label'])
|
->setLabel($type['label'])
|
||||||
->setCode($type['code'])
|
->setCode($type['code'])
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function seedPelletTypes(): void
|
||||||
|
{
|
||||||
$pelletTypes = [
|
$pelletTypes = [
|
||||||
['label' => 'JB croissance', 'code' => 'K750'],
|
['label' => 'JB croissance', 'code' => 'K750'],
|
||||||
['label' => 'Genisse herbe', 'code' => 'K500'],
|
['label' => 'Genisse herbe', 'code' => 'K500'],
|
||||||
@@ -175,82 +181,338 @@ class SeedCommand extends Command
|
|||||||
['label' => 'Bovin mise en forme', 'code' => 'K400'],
|
['label' => 'Bovin mise en forme', 'code' => 'K400'],
|
||||||
];
|
];
|
||||||
foreach ($pelletTypes as $type) {
|
foreach ($pelletTypes as $type) {
|
||||||
$upsertByCode(PelletType::class, $type['code'], static function (PelletType $entity) use ($type) {
|
$this->upsertByCode(PelletType::class, $type['code'], static function (PelletType $entity) use ($type) {
|
||||||
$entity
|
$entity
|
||||||
->setLabel($type['label'])
|
->setLabel($type['label'])
|
||||||
->setCode($type['code'])
|
->setCode($type['code'])
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function seedBuildings(): void
|
||||||
|
{
|
||||||
$buildings = [
|
$buildings = [
|
||||||
['label' => 'Bâtiment 1', 'code' => 'B1'],
|
['label' => 'Bâtiment 1', 'code' => 'B1'],
|
||||||
['label' => 'Bâtiment 2', 'code' => 'B2'],
|
['label' => 'Bâtiment 2', 'code' => 'B2'],
|
||||||
['label' => 'Bâtiment 3', 'code' => 'B3'],
|
['label' => 'Bâtiment 3', 'code' => 'B3'],
|
||||||
];
|
];
|
||||||
foreach ($buildings as $buildingData) {
|
foreach ($buildings as $buildingData) {
|
||||||
$upsertByCode(Building::class, $buildingData['code'], static function (Building $entity) use ($buildingData) {
|
$this->upsertByCode(Building::class, $buildingData['code'], static function (Building $entity) use ($buildingData) {
|
||||||
$entity
|
$entity
|
||||||
->setLabel($buildingData['label'])
|
->setLabel($buildingData['label'])
|
||||||
->setCode($buildingData['code'])
|
->setCode($buildingData['code'])
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function seedReceptionTypes(): void
|
||||||
|
{
|
||||||
$receptionTypes = [
|
$receptionTypes = [
|
||||||
['label' => 'Marchandises', 'code' => 'MARCHANDISES'],
|
['label' => 'Marchandises', 'code' => 'MARCHANDISES'],
|
||||||
['label' => 'Bovins', 'code' => 'BOVINS'],
|
['label' => 'Bovins', 'code' => 'BOVINS'],
|
||||||
];
|
];
|
||||||
foreach ($receptionTypes as $type) {
|
foreach ($receptionTypes as $type) {
|
||||||
$upsertByCode(ReceptionType::class, $type['code'], static function (ReceptionType $entity) use ($type) {
|
$this->upsertByCode(ReceptionType::class, $type['code'], static function (ReceptionType $entity) use ($type) {
|
||||||
$entity
|
$entity
|
||||||
->setLabel($type['label'])
|
->setLabel($type['label'])
|
||||||
->setCode($type['code'])
|
->setCode($type['code'])
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$address = $addressRepo->findOneBy([
|
private function seedSuppliers(): void
|
||||||
'label' => 'LIOT CHATELLERAULT',
|
{
|
||||||
'postalCode' => '86100',
|
$suppliers = [
|
||||||
|
[
|
||||||
|
'name' => 'LIOT',
|
||||||
|
'email' => 'lpc.contacts@lpc-liot.fr',
|
||||||
|
'phone' => '05.49.20.09.10',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'LIOT CHATELLERAULT',
|
||||||
|
'street' => "14 Allée d'Argenson",
|
||||||
|
'street2' => 'ZI Nord',
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'CHATELLERAULT',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'ARNAULT EURL',
|
||||||
|
'email' => 'eurl.arnault86@orange.fr',
|
||||||
|
'phone' => '05.49.02.65.27',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'ARNAULT EURL',
|
||||||
|
'street' => 'Moulin du Guéret',
|
||||||
|
'street2' => 'B.P 30425',
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'Antran',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'EARL DES GONNIERES',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => '06.80.14.18.82',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'EARL DES GONNIERES',
|
||||||
|
'street' => "27 Route d'Ingrandes",
|
||||||
|
'street2' => 'Les Gonnières',
|
||||||
|
'postalCode' => '86220',
|
||||||
|
'city' => 'OYRE',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'EARL LESIGNY BABY',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => '05.49.86.17.95',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'EARL LESIGNY BABY',
|
||||||
|
'street' => '2 Lieu Dit Les Bouquins',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86270',
|
||||||
|
'city' => 'LESIGNY',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'FEDER',
|
||||||
|
'email' => 'contact@uco-feder.fr',
|
||||||
|
'phone' => '03.85.24.25.50',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'FEDER',
|
||||||
|
'street' => 'Molaise',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '71120',
|
||||||
|
'city' => 'CHAROLLES',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => "GAEC DE L'ESPOIR",
|
||||||
|
'email' => 'contact@uco-feder.fr',
|
||||||
|
'phone' => '05.49.86.57.24',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => "GAEC DE L'ESPOIR",
|
||||||
|
'street' => 'La Moujonnerie',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86450',
|
||||||
|
'city' => 'PLEUMARTIN',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'GRAVELEAU',
|
||||||
|
'email' => 'contact@graveleau-sarl.fr',
|
||||||
|
'phone' => '05.49.23.51.66',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'GRAVELEAU',
|
||||||
|
'street' => '3, Le Jeu',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86220',
|
||||||
|
'city' => 'INGRANDES',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'LORTHOLARY',
|
||||||
|
'email' => 'contact86@lortholarybetail.com',
|
||||||
|
'phone' => '05.49.52.77.10',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'LORTHOLARY',
|
||||||
|
'street' => 'Ferme de Geniec',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86550',
|
||||||
|
'city' => 'MIGNALOUX BEAUVOIR',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'NATERA',
|
||||||
|
'email' => 'contact86@lortholarybetail.com',
|
||||||
|
'phone' => '05.65.67.89.46',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'NATERA',
|
||||||
|
'street' => 'Bd des Balquières',
|
||||||
|
'street2' => 'BP 3220',
|
||||||
|
'postalCode' => '12032',
|
||||||
|
'city' => 'RODEZ CEDEX 9',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'SCEA des Bariollières',
|
||||||
|
'email' => 'elisregnier@gmail.com',
|
||||||
|
'phone' => '06.09.37.65.61',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'SCEA des Bariollières',
|
||||||
|
'street' => '2 rue des Barriollières',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86220',
|
||||||
|
'city' => 'INGRANDES',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'SCEA SENE',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => null,
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'SCEA SENE',
|
||||||
|
'street' => '3 Route de la Roche Posay',
|
||||||
|
'street2' => 'Les Girouettes',
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'CHATELLERAULT',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'TERRENA',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => '02.51.67.17.98',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'TERRENA',
|
||||||
|
'street' => 'La Blanchardière',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '44522',
|
||||||
|
'city' => 'MESANGER',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'TRICHERIE COOPERATIVE',
|
||||||
|
'email' => 'contact@cooptricherie.fr',
|
||||||
|
'phone' => '05.49.19.44.33',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'TRICHERIE COOPERATIVE',
|
||||||
|
'street' => 'B.P n°2',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86490',
|
||||||
|
'city' => 'BEAUMONT',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'TURPAULT Muriel',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => null,
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'TURPAULT Muriel',
|
||||||
|
'street' => '23Bis Rue Marcel Pagnol',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'TARGE',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($suppliers as $supplierData) {
|
||||||
|
$supplier = $this->upsertByName(Supplier::class, $supplierData['name'], static function (Supplier $supplier) use ($supplierData) {
|
||||||
|
$supplier
|
||||||
|
->setName($supplierData['name'])
|
||||||
|
->setEmail($supplierData['email'])
|
||||||
|
->setPhone($supplierData['phone'])
|
||||||
|
;
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach ($supplierData['addresses'] as $addressData) {
|
||||||
|
$address = $this->upsertAddress($addressData);
|
||||||
|
if (!$supplier->getAddresses()->contains($address)) {
|
||||||
|
$supplier->getAddresses()->add($address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->entityManager->persist($supplier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function upsertByCode(string $entityClass, string $code, callable $apply): object
|
||||||
|
{
|
||||||
|
$repo = $this->entityManager->getRepository($entityClass);
|
||||||
|
$entity = $repo->findOneBy(['code' => $code]);
|
||||||
|
if (!$entity) {
|
||||||
|
$entity = new $entityClass();
|
||||||
|
++$this->created;
|
||||||
|
} else {
|
||||||
|
++$this->updated;
|
||||||
|
}
|
||||||
|
$apply($entity);
|
||||||
|
$this->entityManager->persist($entity);
|
||||||
|
|
||||||
|
return $entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function upsertByName(string $entityClass, string $name, callable $apply): object
|
||||||
|
{
|
||||||
|
$repo = $this->entityManager->getRepository($entityClass);
|
||||||
|
$entity = $repo->findOneBy(['name' => $name]);
|
||||||
|
if (!$entity) {
|
||||||
|
$entity = new $entityClass();
|
||||||
|
++$this->created;
|
||||||
|
} else {
|
||||||
|
++$this->updated;
|
||||||
|
}
|
||||||
|
$apply($entity);
|
||||||
|
$this->entityManager->persist($entity);
|
||||||
|
|
||||||
|
return $entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function upsertAddress(array $addressData): Address
|
||||||
|
{
|
||||||
|
$addressRepo = $this->entityManager->getRepository(Address::class);
|
||||||
|
$address = $addressRepo->findOneBy([
|
||||||
|
'label' => $addressData['label'],
|
||||||
|
'postalCode' => $addressData['postalCode'],
|
||||||
]);
|
]);
|
||||||
if (!$address) {
|
if (!$address) {
|
||||||
$address = new Address();
|
$address = new Address();
|
||||||
++$created;
|
++$this->created;
|
||||||
} else {
|
} else {
|
||||||
++$updated;
|
++$this->updated;
|
||||||
}
|
}
|
||||||
$address
|
$address
|
||||||
->setLabel('LIOT CHATELLERAULT')
|
->setLabel($addressData['label'])
|
||||||
->setStreet("14 Allée d'Argenson")
|
->setStreet($addressData['street'])
|
||||||
->setStreet2('ZI Nord')
|
->setStreet2($addressData['street2'])
|
||||||
->setPostalCode('86100')
|
->setPostalCode($addressData['postalCode'])
|
||||||
->setCity('CHATELLERAULT')
|
->setCity($addressData['city'])
|
||||||
->setCountryCode('FR')
|
->setCountryCode($addressData['countryCode'])
|
||||||
;
|
;
|
||||||
$this->entityManager->persist($address);
|
$this->entityManager->persist($address);
|
||||||
|
|
||||||
$supplier = $supplierRepo->findOneBy(['name' => 'LIOT']);
|
return $address;
|
||||||
if (!$supplier) {
|
|
||||||
$supplier = new Supplier();
|
|
||||||
++$created;
|
|
||||||
} else {
|
|
||||||
++$updated;
|
|
||||||
}
|
|
||||||
$supplier
|
|
||||||
->setName('LIOT')
|
|
||||||
->setEmail('lpc.contacts@lpc-liot.fr')
|
|
||||||
->setPhone('05.49.20.09.10')
|
|
||||||
;
|
|
||||||
if (!$supplier->getAddresses()->contains($address)) {
|
|
||||||
$supplier->getAddresses()->add($address);
|
|
||||||
}
|
|
||||||
$this->entityManager->persist($supplier);
|
|
||||||
|
|
||||||
$this->entityManager->flush();
|
|
||||||
|
|
||||||
$io->success(sprintf('Seed completed: %d created, %d updated.', $created, $updated));
|
|
||||||
|
|
||||||
return Command::SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,12 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\DataFixtures;
|
namespace App\DataFixtures;
|
||||||
|
|
||||||
|
use App\Entity\Address;
|
||||||
use App\Entity\Building;
|
use App\Entity\Building;
|
||||||
use App\Entity\MerchandiseType;
|
use App\Entity\MerchandiseType;
|
||||||
use App\Entity\PelletType;
|
use App\Entity\PelletType;
|
||||||
use App\Entity\ReceptionType;
|
use App\Entity\ReceptionType;
|
||||||
|
use App\Entity\Supplier;
|
||||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
|
|
||||||
@@ -67,6 +69,242 @@ class ReferenceFixtures extends Fixture
|
|||||||
$manager->persist($receptionType);
|
$manager->persist($receptionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$suppliers = [
|
||||||
|
[
|
||||||
|
'name' => 'LIOT',
|
||||||
|
'email' => 'lpc.contacts@lpc-liot.fr',
|
||||||
|
'phone' => '05.49.20.09.10',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'LIOT CHATELLERAULT',
|
||||||
|
'street' => "14 Allée d'Argenson",
|
||||||
|
'street2' => 'ZI Nord',
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'CHATELLERAULT',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'ARNAULT EURL',
|
||||||
|
'email' => 'eurl.arnault86@orange.fr',
|
||||||
|
'phone' => '05.49.02.65.27',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'ARNAULT EURL',
|
||||||
|
'street' => 'Moulin du Guéret',
|
||||||
|
'street2' => 'B.P 30425',
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'Antran',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'EARL DES GONNIERES',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => '06.80.14.18.82',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'EARL DES GONNIERES',
|
||||||
|
'street' => "27 Route d'Ingrandes",
|
||||||
|
'street2' => 'Les Gonnières',
|
||||||
|
'postalCode' => '86220',
|
||||||
|
'city' => 'OYRE',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'EARL LESIGNY BABY',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => '05.49.86.17.95',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'EARL LESIGNY BABY',
|
||||||
|
'street' => '2 Lieu Dit Les Bouquins',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86270',
|
||||||
|
'city' => 'LESIGNY',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'FEDER',
|
||||||
|
'email' => 'contact@uco-feder.fr',
|
||||||
|
'phone' => '03.85.24.25.50',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'FEDER',
|
||||||
|
'street' => 'Molaise',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '71120',
|
||||||
|
'city' => 'CHAROLLES',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => "GAEC DE L'ESPOIR",
|
||||||
|
'email' => 'contact@uco-feder.fr',
|
||||||
|
'phone' => '05.49.86.57.24',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => "GAEC DE L'ESPOIR",
|
||||||
|
'street' => 'La Moujonnerie',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86450',
|
||||||
|
'city' => 'PLEUMARTIN',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'GRAVELEAU',
|
||||||
|
'email' => 'contact@graveleau-sarl.fr',
|
||||||
|
'phone' => '05.49.23.51.66',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'GRAVELEAU',
|
||||||
|
'street' => '3, Le Jeu',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86220',
|
||||||
|
'city' => 'INGRANDES',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'LORTHOLARY',
|
||||||
|
'email' => 'contact86@lortholarybetail.com',
|
||||||
|
'phone' => '05.49.52.77.10',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'LORTHOLARY',
|
||||||
|
'street' => 'Ferme de Geniec',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86550',
|
||||||
|
'city' => 'MIGNALOUX BEAUVOIR',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'NATERA',
|
||||||
|
'email' => 'contact86@lortholarybetail.com',
|
||||||
|
'phone' => '05.65.67.89.46',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'NATERA',
|
||||||
|
'street' => 'Bd des Balquières',
|
||||||
|
'street2' => 'BP 3220',
|
||||||
|
'postalCode' => '12032',
|
||||||
|
'city' => 'RODEZ CEDEX 9',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'SCEA des Bariollières',
|
||||||
|
'email' => 'elisregnier@gmail.com',
|
||||||
|
'phone' => '06.09.37.65.61',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'SCEA des Bariollières',
|
||||||
|
'street' => '2 rue des Barriollières',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86220',
|
||||||
|
'city' => 'INGRANDES',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'SCEA SENE',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => null,
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'SCEA SENE',
|
||||||
|
'street' => '3 Route de la Roche Posay',
|
||||||
|
'street2' => 'Les Girouettes',
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'CHATELLERAULT',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'TERRENA',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => '02.51.67.17.98',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'TERRENA',
|
||||||
|
'street' => 'La Blanchardière',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '44522',
|
||||||
|
'city' => 'MESANGER',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'TRICHERIE COOPERATIVE',
|
||||||
|
'email' => 'contact@cooptricherie.fr',
|
||||||
|
'phone' => '05.49.19.44.33',
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'TRICHERIE COOPERATIVE',
|
||||||
|
'street' => 'B.P n°2',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86490',
|
||||||
|
'city' => 'BEAUMONT',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'name' => 'TURPAULT Muriel',
|
||||||
|
'email' => null,
|
||||||
|
'phone' => null,
|
||||||
|
'addresses' => [
|
||||||
|
[
|
||||||
|
'label' => 'TURPAULT Muriel',
|
||||||
|
'street' => '23Bis Rue Marcel Pagnol',
|
||||||
|
'street2' => null,
|
||||||
|
'postalCode' => '86100',
|
||||||
|
'city' => 'TARGE',
|
||||||
|
'countryCode' => 'FR',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($suppliers as $supplierData) {
|
||||||
|
$supplier = new Supplier()
|
||||||
|
->setName($supplierData['name'])
|
||||||
|
->setEmail($supplierData['email'])
|
||||||
|
->setPhone($supplierData['phone'])
|
||||||
|
;
|
||||||
|
|
||||||
|
foreach ($supplierData['addresses'] as $addressData) {
|
||||||
|
$address = new Address()
|
||||||
|
->setLabel($addressData['label'])
|
||||||
|
->setStreet($addressData['street'])
|
||||||
|
->setStreet2($addressData['street2'])
|
||||||
|
->setPostalCode($addressData['postalCode'])
|
||||||
|
->setCity($addressData['city'])
|
||||||
|
->setCountryCode($addressData['countryCode'])
|
||||||
|
;
|
||||||
|
$manager->persist($address);
|
||||||
|
$supplier->getAddresses()->add($address);
|
||||||
|
}
|
||||||
|
|
||||||
|
$manager->persist($supplier);
|
||||||
|
}
|
||||||
|
|
||||||
$manager->flush();
|
$manager->flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
70
src/Entity/BovineType.php
Normal file
70
src/Entity/BovineType.php
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?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]
|
||||||
|
#[ApiResource(
|
||||||
|
operations: [
|
||||||
|
new Get(
|
||||||
|
requirements: ['id' => '\d+'],
|
||||||
|
normalizationContext: ['groups' => ['bovine-type:read']],
|
||||||
|
),
|
||||||
|
new GetCollection(
|
||||||
|
normalizationContext: ['groups' => ['bovine-type:read']],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
security: "is_granted('ROLE_USER')",
|
||||||
|
)]
|
||||||
|
class BovineType
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
#[Groups(['bovine-type:read', 'reception:read', 'reception-bovine:read'])]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 120)]
|
||||||
|
#[Groups(['bovine-type:read', 'reception:read', 'reception-bovine:read'])]
|
||||||
|
private ?string $label = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 50)]
|
||||||
|
#[Groups(['bovine-type:read', 'reception:read', 'reception-bovine:read'])]
|
||||||
|
private ?string $code = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLabel(): ?string
|
||||||
|
{
|
||||||
|
return $this->label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLabel(string $label): static
|
||||||
|
{
|
||||||
|
$this->label = $label;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCode(): ?string
|
||||||
|
{
|
||||||
|
return $this->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCode(string $code): static
|
||||||
|
{
|
||||||
|
$this->code = $code;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,27 +72,27 @@ class Reception
|
|||||||
#[ORM\Id]
|
#[ORM\Id]
|
||||||
#[ORM\GeneratedValue]
|
#[ORM\GeneratedValue]
|
||||||
#[ORM\Column]
|
#[ORM\Column]
|
||||||
#[Groups(['reception:read'])]
|
#[Groups(['reception:read', 'reception-bovine:read'])]
|
||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 20, nullable: true)]
|
#[ORM\Column(length: 20, nullable: true)]
|
||||||
#[Groups(['reception:read', 'reception:write'])]
|
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||||
private ?string $licensePlate = null;
|
private ?string $licensePlate = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 20, unique: true, nullable: true)]
|
#[ORM\Column(length: 20, unique: true, nullable: true)]
|
||||||
#[Groups(['reception:read'])]
|
#[Groups(['reception:read', 'reception-bovine:read'])]
|
||||||
private ?string $identificationNumber = null;
|
private ?string $identificationNumber = null;
|
||||||
|
|
||||||
#[ORM\Column(options: ['default' => 0])]
|
#[ORM\Column(options: ['default' => 0])]
|
||||||
#[Groups(['reception:read', 'reception:write'])]
|
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||||
private int $currentStep = 0;
|
private int $currentStep = 0;
|
||||||
|
|
||||||
#[ORM\Column(options: ['default' => false])]
|
#[ORM\Column(options: ['default' => false])]
|
||||||
#[Groups(['reception:read', 'reception:write'])]
|
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||||
private bool $isValid = false;
|
private bool $isValid = false;
|
||||||
|
|
||||||
#[ORM\Column(name: 'date_reception', type: 'datetime_immutable')]
|
#[ORM\Column(name: 'date_reception', type: 'datetime_immutable')]
|
||||||
#[Groups(['reception:read', 'reception:write'])]
|
#[Groups(['reception:read', 'reception:write', 'reception-bovine:read'])]
|
||||||
#[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
|
#[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])]
|
||||||
private ?DateTimeImmutable $receptionDate = null;
|
private ?DateTimeImmutable $receptionDate = null;
|
||||||
|
|
||||||
@@ -168,6 +168,20 @@ class Reception
|
|||||||
#[ApiProperty(readableLink: true)]
|
#[ApiProperty(readableLink: true)]
|
||||||
private ?Driver $driver = null;
|
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(
|
public function __construct(
|
||||||
?DateTimeImmutable $receptionDate = null,
|
?DateTimeImmutable $receptionDate = null,
|
||||||
) {
|
) {
|
||||||
@@ -175,6 +189,7 @@ class Reception
|
|||||||
$this->weights = new ArrayCollection();
|
$this->weights = new ArrayCollection();
|
||||||
$this->buildings = new ArrayCollection();
|
$this->buildings = new ArrayCollection();
|
||||||
$this->pelletBuildings = new ArrayCollection();
|
$this->pelletBuildings = new ArrayCollection();
|
||||||
|
$this->bovines_types = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
@@ -469,4 +484,46 @@ 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
109
src/Entity/ReceptionBovine.php
Normal file
109
src/Entity/ReceptionBovine.php
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/Repository/BovineTypeRepository.php
Normal file
45
src/Repository/BovineTypeRepository.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\BovineType;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<BovineType>
|
||||||
|
*/
|
||||||
|
class BovineTypeRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, BovineType::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return BovineType[] Returns an array of BovineType objects
|
||||||
|
// */
|
||||||
|
// public function findByExampleField($value): array
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('b')
|
||||||
|
// ->andWhere('b.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->orderBy('b.id', 'ASC')
|
||||||
|
// ->setMaxResults(10)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function findOneBySomeField($value): ?BovineType
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('b')
|
||||||
|
// ->andWhere('b.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getOneOrNullResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
}
|
||||||
45
src/Repository/ReceptionBovineRepository.php
Normal file
45
src/Repository/ReceptionBovineRepository.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\ReceptionBovine;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<ReceptionBovine>
|
||||||
|
*/
|
||||||
|
class ReceptionBovineRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, ReceptionBovine::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return ReceptionBovine[] Returns an array of ReceptionBovine objects
|
||||||
|
// */
|
||||||
|
// public function findByExampleField($value): array
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('r')
|
||||||
|
// ->andWhere('r.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->orderBy('r.id', 'ASC')
|
||||||
|
// ->setMaxResults(10)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function findOneBySomeField($value): ?ReceptionBovine
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('r')
|
||||||
|
// ->andWhere('r.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getOneOrNullResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -160,6 +160,15 @@
|
|||||||
".editorconfig"
|
".editorconfig"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"symfony/maker-bundle": {
|
||||||
|
"version": "1.65",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "1.0",
|
||||||
|
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
||||||
|
}
|
||||||
|
},
|
||||||
"symfony/monolog-bundle": {
|
"symfony/monolog-bundle": {
|
||||||
"version": "4.0",
|
"version": "4.0",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|||||||
102
tests/BovinIdentificationProviderTest.php
Normal file
102
tests/BovinIdentificationProviderTest.php
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Tests\State;
|
||||||
|
|
||||||
|
use ApiPlatform\Metadata\Operation;
|
||||||
|
use App\State\BovinIdentificationProvider;
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Api\BovinApiInterface;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\AnimalFileDto;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\BovinIdentificationDto;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\BovinRef;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\DateValueDto;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\ExploitationRef;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\MovementDto;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\ParentInfoDto;
|
||||||
|
use Malio\EdnotifBundle\Bovin\Dto\PresencePeriodDto;
|
||||||
|
use Malio\EdnotifBundle\Shared\Dto\StandardResponseDto;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class BovinIdentificationProviderTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testReturnsNullWhenNumeroNationalMissing(): void
|
||||||
|
{
|
||||||
|
$api = $this->createMock(BovinApiInterface::class);
|
||||||
|
$api->expects(self::never())->method('getAnimalFile');
|
||||||
|
|
||||||
|
$provider = new BovinIdentificationProvider($api);
|
||||||
|
|
||||||
|
$result = $provider->provide($this->createStub(Operation::class), []);
|
||||||
|
|
||||||
|
self::assertNull($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMapsIdentificationAndPresencePeriods(): void
|
||||||
|
{
|
||||||
|
$api = $this->createMock(BovinApiInterface::class);
|
||||||
|
|
||||||
|
$identification = new BovinIdentificationDto(
|
||||||
|
bovin: new BovinRef('FR', 'IGNORED'),
|
||||||
|
sex: 'F',
|
||||||
|
breedType: 'LIM',
|
||||||
|
birthDate: new DateValueDto(new DateTimeImmutable('2024-01-02'), 'Y'),
|
||||||
|
workNumber: 'W123',
|
||||||
|
isFilie: true,
|
||||||
|
motherCarrier: new ParentInfoDto(new BovinRef('FR', 'MOM1'), 'CHA'),
|
||||||
|
fatherIpg: new ParentInfoDto(new BovinRef('FR', 'DAD1'), 'BBB'),
|
||||||
|
birthExploitation: new ExploitationRef('FR', 'EXP1'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$presencePeriods = [
|
||||||
|
new PresencePeriodDto(
|
||||||
|
new MovementDto(new DateTimeImmutable('2024-03-01'), 'ENTRY', null),
|
||||||
|
new MovementDto(new DateTimeImmutable('2024-03-10'), 'EXIT', null),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
$animalFile = new AnimalFileDto(
|
||||||
|
new StandardResponseDto(true, null),
|
||||||
|
$identification,
|
||||||
|
$presencePeriods,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
$api->expects(self::once())
|
||||||
|
->method('getAnimalFile')
|
||||||
|
->with('FR123', 'FR')
|
||||||
|
->willReturn($animalFile)
|
||||||
|
;
|
||||||
|
|
||||||
|
$provider = new BovinIdentificationProvider($api);
|
||||||
|
|
||||||
|
$result = $provider->provide(
|
||||||
|
$this->createStub(Operation::class),
|
||||||
|
['numeroNational' => 'FR123']
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertNotNull($result);
|
||||||
|
self::assertSame('FR123', $result->numeroNational);
|
||||||
|
self::assertSame('F', $result->sex);
|
||||||
|
self::assertSame('LIM', $result->breedType);
|
||||||
|
self::assertSame('W123', $result->workNumber);
|
||||||
|
self::assertSame('2024-01-02', $result->birthDate);
|
||||||
|
self::assertSame('Y', $result->birthDateCompletenessFlag);
|
||||||
|
self::assertTrue($result->isFilie);
|
||||||
|
self::assertSame('MOM1', $result->motherNationalNumber);
|
||||||
|
self::assertSame('CHA', $result->motherBreedType);
|
||||||
|
self::assertSame('DAD1', $result->fatherNationalNumber);
|
||||||
|
self::assertSame('BBB', $result->fatherBreedType);
|
||||||
|
self::assertSame('EXP1', $result->birthExploitationNumber);
|
||||||
|
|
||||||
|
self::assertCount(1, $result->presencePeriods);
|
||||||
|
self::assertSame('2024-03-01', $result->presencePeriods[0]->entryDate);
|
||||||
|
self::assertSame('ENTRY', $result->presencePeriods[0]->entryCause);
|
||||||
|
self::assertSame('2024-03-10', $result->presencePeriods[0]->exitDate);
|
||||||
|
self::assertSame('EXIT', $result->presencePeriods[0]->exitCause);
|
||||||
|
}
|
||||||
|
}
|
||||||
48
tests/State/MeProviderTest.php
Normal file
48
tests/State/MeProviderTest.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Tests\State;
|
||||||
|
|
||||||
|
use ApiPlatform\Metadata\Operation;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\State\MeProvider;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class MeProviderTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testProvideReturnUser(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
|
||||||
|
$security = $this->createStub(Security::class);
|
||||||
|
$security->method('getUser')->willReturn($user);
|
||||||
|
|
||||||
|
$provider = new MeProvider($security);
|
||||||
|
|
||||||
|
$result = $provider->provide($this->createStub(Operation::class));
|
||||||
|
|
||||||
|
self::assertSame($user, $result);
|
||||||
|
self::assertInstanceOf(User::class, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testProvideThrowAccessDeniedException(): void
|
||||||
|
{
|
||||||
|
$user = null;
|
||||||
|
|
||||||
|
$security = $this->createStub(Security::class);
|
||||||
|
$security->method('getUser')->willReturn($user);
|
||||||
|
|
||||||
|
$provider = new MeProvider($security);
|
||||||
|
|
||||||
|
$this->expectException(AccessDeniedException::class);
|
||||||
|
$this->expectExceptionMessage('User not authenticated.');
|
||||||
|
|
||||||
|
$provider->provide($this->createStub(Operation::class));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user