Compare commits
2 Commits
v0.0.45
...
feat/poc-i
| Author | SHA1 | Date | |
|---|---|---|---|
| 941e3d2258 | |||
| 6421419812 |
@@ -1,2 +1,2 @@
|
||||
parameters:
|
||||
app.version: '0.0.45'
|
||||
app.version: '0.0.44'
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
label="Client"
|
||||
:options="customers.map((customer) => ({
|
||||
value: String(customer.id),
|
||||
label: customer.name || `Client #${customer.id}`
|
||||
label: customer.label
|
||||
}))"
|
||||
:loading="isLoadingCustomers"
|
||||
wrapper-class="col-start-1 row-start-5"
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-y-8 gap-x-80 mb-10 py-12">
|
||||
<UiTextInput id="customer-name" v-model="form.name" label="Nom du client" :disabled="!auth.isAdmin"/>
|
||||
<UiTextInput id="customer-phone" v-model="form.phone" label="Téléphone" :disabled="!auth.isAdmin"/>
|
||||
<UiTextInput id="customer-email" v-model="form.email" label="Email" :disabled="!auth.isAdmin"/>
|
||||
<UiTextInput id="customer-label" v-model="form.label" label="Nom du client" :disabled="!auth.isAdmin"/>
|
||||
<UiTextInput id="customer-code" v-model="form.code" label="Code" :disabled="!auth.isAdmin"/>
|
||||
</div>
|
||||
|
||||
<div class="mx-24 mb-4 py-6 border-t border-black"></div>
|
||||
@@ -95,9 +94,8 @@ const resolveId = (param: unknown) => {
|
||||
const customerId = computed(() => resolveId(route.params.id))
|
||||
const isLoading = ref(false)
|
||||
const form = reactive<CustomerFormData>({
|
||||
name: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
label: "",
|
||||
code: "",
|
||||
addresses: [],
|
||||
})
|
||||
|
||||
@@ -124,9 +122,8 @@ const goToEditAddress = (addressId: number | null) => {
|
||||
|
||||
const hydrateFromCustomer = (customer: CustomerData | null) => {
|
||||
if (!customer) return
|
||||
form.name = customer.name ?? ""
|
||||
form.phone = customer.phone ?? ""
|
||||
form.email = customer.email ?? ""
|
||||
form.label = customer.label ?? ""
|
||||
form.code = customer.code ?? ""
|
||||
if (!Array.isArray(customer.addresses) || customer.addresses.length === 0) {
|
||||
form.addresses = []
|
||||
return
|
||||
@@ -168,14 +165,12 @@ async function validate() {
|
||||
isLoading.value = true
|
||||
|
||||
try {
|
||||
const name = form.name.trim()
|
||||
const phone = form.phone?.trim() || null
|
||||
const email = form.email?.trim() || null
|
||||
const label = form.label.trim()
|
||||
const code = form.code.trim()
|
||||
|
||||
const customerPayload: CustomerPayload = {
|
||||
name,
|
||||
phone,
|
||||
email,
|
||||
label,
|
||||
code,
|
||||
}
|
||||
let targetId: number | null = null
|
||||
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
<div v-if="auth.isAdmin" class="mt-6 border border-slate-200 mb-16">
|
||||
<div class="max-h-96 overflow-y-auto">
|
||||
<div
|
||||
class="sticky top-0 z-10 grid grid-cols-8 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide"
|
||||
class="sticky top-0 z-10 grid grid-cols-7 gap-4 bg-slate-100 px-4 py-3 text-sm font-semibold uppercase tracking-wide"
|
||||
>
|
||||
<div>Nom</div>
|
||||
<div>Téléphone</div>
|
||||
<div>Email</div>
|
||||
<div>Code</div>
|
||||
<div>Rue</div>
|
||||
<div>Complément</div>
|
||||
<div>Code Postal</div>
|
||||
@@ -27,18 +26,17 @@
|
||||
</div>
|
||||
|
||||
<div v-if="customerList.length === 0" class="px-4 py-6 text-slate-400">
|
||||
Aucun client.
|
||||
Aucun fournisseur.
|
||||
</div>
|
||||
|
||||
<div v-for="customer in customerList" :key="customer.id">
|
||||
<div
|
||||
v-if="!customer.addresses || customer.addresses.length === 0"
|
||||
class="grid grid-cols-8 border-t gap-4 px-4 py-2 hover:bg-slate-50 cursor-pointer"
|
||||
class="grid grid-cols-7 border-t gap-4 px-4 py-2 hover:bg-slate-50 cursor-pointer"
|
||||
@click="goToCustomer(customer.id)"
|
||||
>
|
||||
<div class="truncate">{{ customer.name || "—" }}</div>
|
||||
<div class="truncate">{{ customer.phone || "—" }}</div>
|
||||
<div class="truncate">{{ customer.email || "—" }}</div>
|
||||
<div class="truncate">{{ customer.label }}</div>
|
||||
<div class="truncate">{{ customer.code }}</div>
|
||||
<div class="col-span-1">Pas d'adresse</div>
|
||||
<div class="uppercase truncate">{{"—"}}</div>
|
||||
<div class="uppercase truncate">{{"—"}}</div>
|
||||
@@ -50,15 +48,14 @@
|
||||
<div
|
||||
v-for="(address, idx) in customer.addresses"
|
||||
:key="address.id ?? `${customer.id}-${idx}-${address.street}-${address.postalCode}`"
|
||||
class="grid grid-cols-8 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer"
|
||||
class="grid grid-cols-7 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer"
|
||||
:class="idx > 0 ? 'pl-4 border-l-4 border-l-slate-200 bg-slate-50' : ''"
|
||||
@click="goToCustomer(customer.id)"
|
||||
>
|
||||
<div class="truncate">
|
||||
{{ idx === 0 ? (customer.name || "—") : "↳" }}
|
||||
{{ idx === 0 ? customer.label : "↳" }}
|
||||
</div>
|
||||
<div class="truncate">{{ idx === 0 ? (customer.phone || "—") : "" }}</div>
|
||||
<div class="truncate">{{ idx === 0 ? (customer.email || "—") : "" }}</div>
|
||||
<div class="truncate">{{ idx === 0 ? customer.code : "" }}</div>
|
||||
<div class="truncate">{{ address.street || "—" }}</div>
|
||||
<div class="truncate">{{ address.street2 || "—" }}</div>
|
||||
<div>{{ address.postalCode || "—" }}</div>
|
||||
@@ -69,12 +66,11 @@
|
||||
|
||||
<template v-else>
|
||||
<div
|
||||
class="grid grid-cols-8 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer"
|
||||
class="grid grid-cols-7 hover:bg-slate-50 border-t gap-4 px-4 py-2 cursor-pointer"
|
||||
@click="goToCustomer(customer.id)"
|
||||
>
|
||||
<div class="truncate">{{ customer.name || "—" }}</div>
|
||||
<div class="truncate">{{ customer.phone || "—" }}</div>
|
||||
<div class="truncate">{{ customer.email || "—" }}</div>
|
||||
<div class="truncate">{{ customer.label }}</div>
|
||||
<div class="truncate">{{ customer.code }}</div>
|
||||
<div class="col-span-5 text-slate-400">
|
||||
Adresses non chargées
|
||||
</div>
|
||||
|
||||
49
frontend/pages/identification-bovin.vue
Normal file
49
frontend/pages/identification-bovin.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<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>
|
||||
@@ -4,22 +4,19 @@ export type CustomerAddresses = AddressFormData[] | string[]
|
||||
|
||||
export interface CustomerData {
|
||||
id: number
|
||||
name: string
|
||||
phone?: string | null
|
||||
email?: string | null
|
||||
label: string
|
||||
code?: string | null
|
||||
addresses: CustomerAddresses
|
||||
}
|
||||
|
||||
export interface CustomerFormData {
|
||||
name: string
|
||||
phone?: string
|
||||
email?: string
|
||||
label: string
|
||||
code?: string
|
||||
addresses: AddressFormData[]
|
||||
}
|
||||
|
||||
export type CustomerPayload = {
|
||||
name: string
|
||||
phone?: string | null
|
||||
email?: string | null
|
||||
label: string
|
||||
code?: string | null
|
||||
addresses?: string[]
|
||||
}
|
||||
|
||||
22
frontend/services/dto/identification-bovin-data.ts
Normal file
22
frontend/services/dto/identification-bovin-data.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
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
|
||||
}
|
||||
25
frontend/services/identification-bovin.ts
Normal file
25
frontend/services/identification-bovin.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
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
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20260213093000 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add name, phone and email fields to customer.';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE customer ADD name VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE customer ADD phone VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE customer ADD email VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('UPDATE customer SET name = label WHERE name IS NULL');
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN name SET NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE customer DROP name');
|
||||
$this->addSql('ALTER TABLE customer DROP phone');
|
||||
$this->addSql('ALTER TABLE customer DROP email');
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20260213101500 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Align customer with supplier: keep name/email/phone and drop label/code.';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN name TYPE VARCHAR(180)');
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN email TYPE VARCHAR(180)');
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN phone TYPE VARCHAR(40)');
|
||||
$this->addSql('ALTER TABLE customer DROP COLUMN label');
|
||||
$this->addSql('ALTER TABLE customer DROP COLUMN code');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE customer ADD label VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE customer ADD code VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('UPDATE customer SET label = name WHERE label IS NULL');
|
||||
$this->addSql("UPDATE customer SET code = regexp_replace(upper(name), '[^A-Z0-9]+', '_', 'g') WHERE code IS NULL");
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN label SET NOT NULL');
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN code SET NOT NULL');
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN email TYPE VARCHAR(255)');
|
||||
$this->addSql('ALTER TABLE customer ALTER COLUMN phone TYPE VARCHAR(255)');
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,8 @@ use App\State\BovinIdentificationProvider;
|
||||
uriTemplate: '/bovins/{numeroNational}/identification',
|
||||
provider: BovinIdentificationProvider::class
|
||||
),
|
||||
]
|
||||
],
|
||||
security: "is_granted('ROLE_USER')",
|
||||
)]
|
||||
final class BovinIdentification
|
||||
{
|
||||
|
||||
@@ -5,15 +5,12 @@ declare(strict_types=1);
|
||||
namespace App\Command;
|
||||
|
||||
use App\Entity\Address;
|
||||
use App\Entity\BovineType;
|
||||
use App\Entity\Building;
|
||||
use App\Entity\Carrier;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\Driver;
|
||||
use App\Entity\MerchandiseType;
|
||||
use App\Entity\PelletType;
|
||||
use App\Entity\ReceptionType;
|
||||
use App\Entity\ShipmentType;
|
||||
use App\Entity\Supplier;
|
||||
use App\Entity\Truck;
|
||||
use App\Entity\Vehicle;
|
||||
@@ -53,11 +50,7 @@ class SeedCommand extends Command
|
||||
$this->seedPelletTypes();
|
||||
$this->seedBuildings();
|
||||
$this->seedReceptionTypes();
|
||||
$this->seedBovineTypes();
|
||||
$this->seedShipmentTypes();
|
||||
$this->seedSuppliers();
|
||||
$this->entityManager->flush();
|
||||
$this->seedCustomers($io);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
@@ -68,7 +61,7 @@ class SeedCommand extends Command
|
||||
|
||||
private function seedTrucks(): array
|
||||
{
|
||||
$trucks = ['Citerne', 'Porteur', 'Plateau', 'Remorque', 'Benne'];
|
||||
$trucks = ['Citerne', 'Porteur'];
|
||||
$citerne = null;
|
||||
$porteur = null;
|
||||
foreach ($trucks as $name) {
|
||||
@@ -230,39 +223,6 @@ class SeedCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private function seedBovineTypes(): void
|
||||
{
|
||||
$bovineTypes = [
|
||||
['label' => 'Limousine', 'code' => '34'],
|
||||
['label' => 'Charolaise', 'code' => '38'],
|
||||
['label' => 'Parthenaise', 'code' => '71'],
|
||||
];
|
||||
foreach ($bovineTypes as $type) {
|
||||
$this->upsertByCode(BovineType::class, $type['code'], static function (BovineType $entity) use ($type) {
|
||||
$entity
|
||||
->setLabel($type['label'])
|
||||
->setCode($type['code'])
|
||||
;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private function seedShipmentTypes(): void
|
||||
{
|
||||
$shipmentTypes = [
|
||||
['label' => 'Bovin de boucherie', 'code' => 'BDB'],
|
||||
['label' => "Bovin d'équarrissage", 'code' => 'BE'],
|
||||
];
|
||||
foreach ($shipmentTypes as $type) {
|
||||
$this->upsertByCode(ShipmentType::class, $type['code'], static function (ShipmentType $entity) use ($type) {
|
||||
$entity
|
||||
->setLabel($type['label'])
|
||||
->setCode($type['code'])
|
||||
;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private function seedSuppliers(): void
|
||||
{
|
||||
$suppliers = [
|
||||
@@ -498,130 +458,6 @@ class SeedCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
private function seedCustomers(SymfonyStyle $io): void
|
||||
{
|
||||
$addressRepo = $this->entityManager->getRepository(Address::class);
|
||||
$customers = [
|
||||
[
|
||||
'name' => 'ARNAULT EURL',
|
||||
'phone' => '05.49.02.65.27',
|
||||
'email' => 'eurl.arnault86@orange.fr',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'ARNAULT EURL',
|
||||
'street' => 'Moulin du Guéret',
|
||||
'street2' => 'B.P 30425',
|
||||
'postalCode' => '86100',
|
||||
'city' => 'Antran',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'COVILIM',
|
||||
'phone' => '05.55.30.03.10',
|
||||
'email' => 'sandra.robineaux@covilim.com',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'COVILIM',
|
||||
'street' => 'Rue de Nexon',
|
||||
'street2' => null,
|
||||
'postalCode' => '87000',
|
||||
'city' => 'LIMOGES',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'Les producteurs de la marche (LPM)',
|
||||
'phone' => '05.55.63.04.53',
|
||||
'email' => 'f.legalliard@lpmcoop.fr',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'Les producteurs de la marche (LPM)',
|
||||
'street' => 'Rue de Nexon',
|
||||
'street2' => null,
|
||||
'postalCode' => '87000',
|
||||
'city' => 'LIMOGES',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'LORTHOLARY BETAIL',
|
||||
'phone' => '05.49.52.77.10',
|
||||
'email' => 'contact86@lortholarybetail.com',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'LORTHOLARY BETAIL',
|
||||
'street' => 'FERME DE GENIEC',
|
||||
'street2' => null,
|
||||
'postalCode' => '86550',
|
||||
'city' => 'MIGNALOUX BEAUVOIR',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'TERRENA',
|
||||
'phone' => '02.51.67.17.98',
|
||||
'email' => null,
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'TERRENA',
|
||||
'street' => 'La Blanchardière',
|
||||
'street2' => null,
|
||||
'postalCode' => '44522',
|
||||
'city' => 'MESANGER',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($customers as $customerData) {
|
||||
$customerName = $customerData['name'] ?? $customerData['label'] ?? null;
|
||||
if (!$customerName) {
|
||||
$io->warning('Customer skipped: missing "name".');
|
||||
|
||||
continue;
|
||||
}
|
||||
$customer = $this->upsertByName(Customer::class, $customerName, static function (Customer $customer) use ($customerData, $customerName) {
|
||||
$customer
|
||||
->setName($customerName)
|
||||
->setPhone($customerData['phone'] ?? null)
|
||||
->setEmail($customerData['email'] ?? null)
|
||||
;
|
||||
});
|
||||
|
||||
$addresses = [];
|
||||
if (isset($customerData['addresses']) && is_array($customerData['addresses'])) {
|
||||
foreach ($customerData['addresses'] as $addressData) {
|
||||
$addresses[] = $this->upsertAddress($addressData);
|
||||
}
|
||||
} else {
|
||||
// Backward compatibility for older seed format with address ids.
|
||||
$addressIds = $customerData['addressIds'] ?? (isset($customerData['addressId']) ? [$customerData['addressId']] : []);
|
||||
foreach ($addressIds as $addressId) {
|
||||
$address = $addressRepo->find($addressId);
|
||||
if (!$address instanceof Address) {
|
||||
$io->warning(sprintf(
|
||||
'Customer "%s" skipped address id %d: not found.',
|
||||
$customerName,
|
||||
$addressId
|
||||
));
|
||||
|
||||
continue;
|
||||
}
|
||||
$addresses[] = $address;
|
||||
}
|
||||
}
|
||||
|
||||
$customer->setAddresses($addresses);
|
||||
$this->entityManager->persist($customer);
|
||||
}
|
||||
}
|
||||
|
||||
private function upsertByCode(string $entityClass, string $code, callable $apply): object
|
||||
{
|
||||
$repo = $this->entityManager->getRepository($entityClass);
|
||||
|
||||
@@ -20,6 +20,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
||||
return [
|
||||
TransportFixtures::class,
|
||||
ReferenceFixtures::class,
|
||||
SupplierFixtures::class,
|
||||
UserFixtures::class,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,13 +5,10 @@ declare(strict_types=1);
|
||||
namespace App\DataFixtures;
|
||||
|
||||
use App\Entity\Address;
|
||||
use App\Entity\BovineType;
|
||||
use App\Entity\Building;
|
||||
use App\Entity\Customer;
|
||||
use App\Entity\MerchandiseType;
|
||||
use App\Entity\PelletType;
|
||||
use App\Entity\ReceptionType;
|
||||
use App\Entity\ShipmentType;
|
||||
use App\Entity\Supplier;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
@@ -20,8 +17,6 @@ class ReferenceFixtures extends Fixture
|
||||
{
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$addressIndex = [];
|
||||
|
||||
$merchandiseTypes = [
|
||||
['label' => 'Foin', 'code' => 'FOIN'],
|
||||
['label' => 'Paille', 'code' => 'PAILLE'],
|
||||
@@ -74,31 +69,6 @@ class ReferenceFixtures extends Fixture
|
||||
$manager->persist($receptionType);
|
||||
}
|
||||
|
||||
$bovineTypes = [
|
||||
['label' => 'Limousine', 'code' => '34'],
|
||||
['label' => 'Charolaise', 'code' => '38'],
|
||||
['label' => 'Parthenaise', 'code' => '71'],
|
||||
];
|
||||
foreach ($bovineTypes as $type) {
|
||||
$bovineType = new BovineType()
|
||||
->setLabel($type['label'])
|
||||
->setCode($type['code'])
|
||||
;
|
||||
$manager->persist($bovineType);
|
||||
}
|
||||
|
||||
$shipmentTypes = [
|
||||
['label' => 'Bovin de boucherie', 'code' => 'BDB'],
|
||||
['label' => "Bovin d'équarrissage", 'code' => 'BE'],
|
||||
];
|
||||
foreach ($shipmentTypes as $type) {
|
||||
$shipmentType = new ShipmentType()
|
||||
->setLabel($type['label'])
|
||||
->setCode($type['code'])
|
||||
;
|
||||
$manager->persist($shipmentType);
|
||||
}
|
||||
|
||||
$suppliers = [
|
||||
[
|
||||
'name' => 'LIOT',
|
||||
@@ -320,129 +290,21 @@ class ReferenceFixtures extends Fixture
|
||||
;
|
||||
|
||||
foreach ($supplierData['addresses'] as $addressData) {
|
||||
$addressKey = sprintf('%s|%s', $addressData['label'], $addressData['postalCode']);
|
||||
if (!isset($addressIndex[$addressKey])) {
|
||||
$addressIndex[$addressKey] = new Address()
|
||||
->setLabel($addressData['label'])
|
||||
->setStreet($addressData['street'])
|
||||
->setStreet2($addressData['street2'])
|
||||
->setPostalCode($addressData['postalCode'])
|
||||
->setCity($addressData['city'])
|
||||
->setCountryCode($addressData['countryCode'])
|
||||
;
|
||||
$manager->persist($addressIndex[$addressKey]);
|
||||
}
|
||||
$address = $addressIndex[$addressKey];
|
||||
$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);
|
||||
}
|
||||
|
||||
$customers = [
|
||||
[
|
||||
'name' => 'ARNAULT EURL',
|
||||
'phone' => '05.49.02.65.27',
|
||||
'email' => 'eurl.arnault86@orange.fr',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'ARNAULT EURL',
|
||||
'street' => 'Moulin du Guéret',
|
||||
'street2' => 'B.P 30425',
|
||||
'postalCode' => '86100',
|
||||
'city' => 'Antran',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'COVILIM',
|
||||
'phone' => '05.55.30.03.10',
|
||||
'email' => 'sandra.robineaux@covilim.com',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'COVILIM',
|
||||
'street' => 'Rue de Nexon',
|
||||
'street2' => null,
|
||||
'postalCode' => '87000',
|
||||
'city' => 'LIMOGES',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'Les producteurs de la marche (LPM)',
|
||||
'phone' => '05.55.63.04.53',
|
||||
'email' => 'f.legalliard@lpmcoop.fr',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'Les producteurs de la marche (LPM)',
|
||||
'street' => 'Rue de Nexon',
|
||||
'street2' => null,
|
||||
'postalCode' => '87000',
|
||||
'city' => 'LIMOGES',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'LORTHOLARY BETAIL',
|
||||
'phone' => '05.49.52.77.10',
|
||||
'email' => 'contact86@lortholarybetail.com',
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'LORTHOLARY BETAIL',
|
||||
'street' => 'FERME DE GENIEC',
|
||||
'street2' => null,
|
||||
'postalCode' => '86550',
|
||||
'city' => 'MIGNALOUX BEAUVOIR',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'name' => 'TERRENA',
|
||||
'phone' => '02.51.67.17.98',
|
||||
'email' => null,
|
||||
'addresses' => [
|
||||
[
|
||||
'label' => 'TERRENA',
|
||||
'street' => 'La Blanchardière',
|
||||
'street2' => null,
|
||||
'postalCode' => '44522',
|
||||
'city' => 'MESANGER',
|
||||
'countryCode' => 'FR',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($customers as $customerData) {
|
||||
$customer = new Customer()
|
||||
->setName($customerData['name'])
|
||||
->setPhone($customerData['phone'])
|
||||
->setEmail($customerData['email'])
|
||||
;
|
||||
|
||||
foreach ($customerData['addresses'] as $addressData) {
|
||||
$addressKey = sprintf('%s|%s', $addressData['label'], $addressData['postalCode']);
|
||||
if (!isset($addressIndex[$addressKey])) {
|
||||
$addressIndex[$addressKey] = new Address()
|
||||
->setLabel($addressData['label'])
|
||||
->setStreet($addressData['street'])
|
||||
->setStreet2($addressData['street2'])
|
||||
->setPostalCode($addressData['postalCode'])
|
||||
->setCity($addressData['city'])
|
||||
->setCountryCode($addressData['countryCode'])
|
||||
;
|
||||
$manager->persist($addressIndex[$addressKey]);
|
||||
}
|
||||
$customer->getAddresses()->add($addressIndex[$addressKey]);
|
||||
}
|
||||
|
||||
$manager->persist($customer);
|
||||
}
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,17 +15,11 @@ class TransportFixtures extends Fixture
|
||||
{
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$citerne = new Truck()->setName('Citerne');
|
||||
$porteur = new Truck()->setName('Porteur');
|
||||
$plateau = new Truck()->setName('Plateau');
|
||||
$remorque = new Truck()->setName('Remorque');
|
||||
$benne = new Truck()->setName('Benne');
|
||||
$citerne = new Truck()->setName('Citerne');
|
||||
$porteur = new Truck()->setName('Porteur');
|
||||
|
||||
$manager->persist($citerne);
|
||||
$manager->persist($porteur);
|
||||
$manager->persist($plateau);
|
||||
$manager->persist($remorque);
|
||||
$manager->persist($benne);
|
||||
|
||||
$liot = new Carrier()
|
||||
->setName('LIOT')
|
||||
|
||||
@@ -47,17 +47,13 @@ class Customer
|
||||
#[Groups(['shipment:read', 'customer:read'])]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(length: 180)]
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Groups(['customer:read', 'customer:write', 'shipment:read'])]
|
||||
private string $name = '';
|
||||
private ?string $label = null;
|
||||
|
||||
#[ORM\Column(length: 180, nullable: true)]
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Groups(['customer:read', 'customer:write', 'shipment:read'])]
|
||||
private ?string $email = null;
|
||||
|
||||
#[ORM\Column(length: 40, nullable: true)]
|
||||
#[Groups(['customer:read', 'customer:write', 'shipment:read'])]
|
||||
private ?string $phone = null;
|
||||
private ?string $code = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Address>
|
||||
@@ -78,40 +74,24 @@ class Customer
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
public function setName(string $name): self
|
||||
public function setLabel(?string $label): void
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
public function getCode(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
public function setEmail(?string $email): self
|
||||
public function setCode(?string $code): void
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPhone(): ?string
|
||||
{
|
||||
return $this->phone;
|
||||
}
|
||||
|
||||
public function setPhone(?string $phone): self
|
||||
{
|
||||
$this->phone = $phone;
|
||||
|
||||
return $this;
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
public function getAddresses(): Collection
|
||||
|
||||
Reference in New Issue
Block a user