Merge remote-tracking branch 'origin/develop' into develop

# Conflicts:
#	.idea/workspace.xml
This commit is contained in:
kevin
2026-02-03 09:30:13 +01:00
6 changed files with 675 additions and 168 deletions
+8 -28
View File
@@ -5,16 +5,13 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="feat : mise à jour du bon de réception"> <list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="feat : mise à jour du bon de réception">
<change beforePath="$PROJECT_DIR$/.idea/dataSources.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/data_source_mapping.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/ferme.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/ferme.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/php.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/php.xml" 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$/composer.json" beforeDir="false" afterPath="$PROJECT_DIR$/composer.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/composer.lock" beforeDir="false" afterPath="$PROJECT_DIR$/composer.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/bundles.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/bundles.php" 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$/symfony.lock" beforeDir="false" afterPath="$PROJECT_DIR$/symfony.lock" 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/components/reception/reception-weight.vue" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/components/reception/reception-weight.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/frontend/composables/usePdfPrinter.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/composables/usePdfPrinter.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Command/SeedCommand.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Command/SeedCommand.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/DataFixtures/ReferenceFixtures.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/DataFixtures/ReferenceFixtures.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" />
@@ -25,11 +22,6 @@
<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" />
@@ -45,7 +37,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="feat/poc-identification-bovin" />
</map> </map>
</option> </option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -63,7 +55,7 @@
</server> </server>
</servers> </servers>
</component> </component>
<component name="PhpWorkspaceProjectConfiguration" interpreter_name="C:/php-8.4.3/php.exe"> <component name="PhpWorkspaceProjectConfiguration">
<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" />
@@ -213,7 +205,6 @@
<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">{
@@ -234,7 +225,6 @@
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;, &quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;develop&quot;, &quot;git-widget-placeholder&quot;: &quot;develop&quot;,
&quot;last_opened_file_path&quot;: &quot;//wsl.localhost/Ubuntu-24.04/home/kevin/Stage/Ferme&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;, &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;, &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;, &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
@@ -267,7 +257,6 @@
<component name="SharedIndexes"> <component name="SharedIndexes">
<attachedChunks> <attachedChunks>
<set> <set>
<option value="bundled-js-predefined-d6986cc7102b-9b0f141eb926-JavaScript-PS-253.30387.85" />
<option value="bundled-php-predefined-a98d8de5180a-0e0d91225499-com.jetbrains.php.sharedIndexes-PS-253.30387.85" /> <option value="bundled-php-predefined-a98d8de5180a-0e0d91225499-com.jetbrains.php.sharedIndexes-PS-253.30387.85" />
</set> </set>
</attachedChunks> </attachedChunks>
@@ -292,8 +281,7 @@
<workItem from="1769696465294" duration="8573000" /> <workItem from="1769696465294" duration="8573000" />
<workItem from="1769756623432" duration="21592000" /> <workItem from="1769756623432" duration="21592000" />
<workItem from="1770015653091" duration="73000" /> <workItem from="1770015653091" duration="73000" />
<workItem from="1770044486061" duration="2800000" /> <workItem from="1770040138216" duration="6492000" />
<workItem from="1770102274718" duration="4645000" />
</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" />
@@ -744,12 +732,4 @@
<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>
@@ -98,6 +98,30 @@ 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 +154,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] = []
} }
@@ -186,7 +214,13 @@ 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)
} }
@@ -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>
+9 -12
View File
@@ -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);
} }
+379 -117
View File
@@ -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;
} }
} }
+238
View File
@@ -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();
} }
} }