diff --git a/CHANGELOG.md b/CHANGELOG.md index 49ccce5..dc8b257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Ajouter dans le fichier .env du frontend * [#275] Lister les expéditions en attente * [#276] Lister les expéditions terminées * [#324] Creation page admin listing clients +* [#326] Admin modification creation client ### Changed diff --git a/frontend/i18n/locales/fr.json b/frontend/i18n/locales/fr.json index a210e30..57c2d34 100644 --- a/frontend/i18n/locales/fr.json +++ b/frontend/i18n/locales/fr.json @@ -115,6 +115,10 @@ "create": "Fournisseur créé avec succès.", "update": "Fournisseur mis à jour avec succès." }, + "customer": { + "create": "Client créé avec succès.", + "update": "Client mis à jour avec succès." + }, "address": { "create": "Adresse créée avec succès.", "update": "Adresse mise à jour avec succès." diff --git a/frontend/pages/admin/customer/[[id]].vue b/frontend/pages/admin/customer/[[id]].vue index 7a779c6..42f47ee 100644 --- a/frontend/pages/admin/customer/[[id]].vue +++ b/frontend/pages/admin/customer/[[id]].vue @@ -1,12 +1,195 @@ + + + + {{ customerId ? "Modifications du client" : "Ajout d'un client" }} + + + {{ customerId ? "Sauvegarder" : "Ajouter" }} + + + + + + + + + + + Adresses client + + Ajouter + + + + + + + Libellé + Rue + Complément + Code postal + Ville + Pays + + + + + + + Aucune adresse. + + + + + + {{ address.label || "—" }} + {{ address.street || "—" }} + {{ address.street2 || "—" }} + {{ address.postalCode || "—" }} + {{ address.city || "—" }} + {{ address.countryCode || "—" }} + + + + + + diff --git a/frontend/pages/admin/customer/address.vue b/frontend/pages/admin/customer/address.vue new file mode 100644 index 0000000..5651496 --- /dev/null +++ b/frontend/pages/admin/customer/address.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/frontend/services/customer.ts b/frontend/services/customer.ts index 04c8faa..29cff05 100644 --- a/frontend/services/customer.ts +++ b/frontend/services/customer.ts @@ -1,23 +1,43 @@ -import { useApi } from '~/composables/useApi' -import type { CustomerData } from '~/services/dto/customer-data' +import { useApi } from "~/composables/useApi" +import type { CustomerData, CustomerPayload } from "~/services/dto/customer-data" export type CustomerListResponse = | CustomerData[] - | { 'hydra:member'?: CustomerData[] } + | { "hydra:member"?: CustomerData[] } export async function getCustomerList(): Promise { const api = useApi() - const response = await api.get('customers', {}, { - toastErrorKey: 'errors.customer.list' + const response = await api.get("customers", {}, { + toastErrorKey: "errors.customer.list", }) - if (Array.isArray(response)) { - return response + if (Array.isArray(response)) return response + if (response && typeof response === "object" && Array.isArray(response["hydra:member"])) { + return response["hydra:member"] } - - if (response && typeof response === 'object' && Array.isArray(response['hydra:member'])) { - return response['hydra:member'] - } - return [] } + +export async function getCustomer(id: number): Promise { + const api = useApi() + return api.get(`customers/${id}`, {}, { + toastErrorKey: "errors.customer.fetch", + }) +} + +export async function updateCustomer(id: number, payload: Partial): Promise { + const api = useApi() + return api.patch(`customers/${id}`, payload, { + toastErrorKey: "errors.customer.update", + toastSuccessKey: "success.customer.update", + }) +} + +export async function createCustomer(payload: CustomerPayload): Promise { + const api = useApi() + return api.post("customers", payload, { + toastErrorKey: "errors.customer.create", + toastSuccessKey: "success.customer.create", + }) +} + diff --git a/frontend/services/dto/customer-data.ts b/frontend/services/dto/customer-data.ts index 57d6f7d..ddaa22d 100644 --- a/frontend/services/dto/customer-data.ts +++ b/frontend/services/dto/customer-data.ts @@ -1,8 +1,22 @@ -import type { AddressData } from "~/services/dto/address-data" +import type { AddressFormData } from "~/services/dto/address-data" + +export type CustomerAddresses = AddressFormData[] | string[] export interface CustomerData { id: number label: string code?: string | null - addresses?: AddressData[] | null + addresses: CustomerAddresses +} + +export interface CustomerFormData { + label: string + code?: string + addresses: AddressFormData[] +} + +export type CustomerPayload = { + label: string + code?: string | null + addresses?: string[] } diff --git a/src/Entity/Customer.php b/src/Entity/Customer.php index ad6e09c..286eb6b 100644 --- a/src/Entity/Customer.php +++ b/src/Entity/Customer.php @@ -8,6 +8,8 @@ use ApiPlatform\Metadata\ApiProperty; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -24,6 +26,16 @@ use Symfony\Component\Serializer\Attribute\Groups; new GetCollection( normalizationContext: ['groups' => ['customer:read']], ), + new Post( + normalizationContext: ['groups' => ['customer:read']], + denormalizationContext: ['groups' => ['customer:write']], + security: "is_granted('ROLE_ADMIN')", + ), + new Patch( + normalizationContext: ['groups' => ['customer:read']], + denormalizationContext: ['groups' => ['customer:write']], + security: "is_granted('ROLE_ADMIN')", + ), ], security: "is_granted('ROLE_USER')", )] @@ -36,11 +48,11 @@ class Customer private ?int $id = null; #[ORM\Column(length: 255)] - #[Groups(['customer:read', 'shipment:read'])] + #[Groups(['customer:read', 'customer:write', 'shipment:read'])] private ?string $label = null; #[ORM\Column(length: 255)] - #[Groups(['customer:read', 'shipment:read'])] + #[Groups(['customer:read', 'customer:write', 'shipment:read'])] private ?string $code = null; /** @@ -48,7 +60,7 @@ class Customer */ #[ORM\ManyToMany(targetEntity: Address::class, inversedBy: 'customers')] #[ORM\JoinTable(name: 'customer_address')] - #[Groups(['customer:read'])] + #[Groups(['customer:read', 'customer:write'])] #[ApiProperty(readableLink: true)] private Collection $addresses; @@ -87,8 +99,29 @@ class Customer return $this->addresses; } - public function setAddresses(Collection $addresses): void + public function setAddresses(iterable $addresses): self { - $this->addresses = $addresses; + $this->addresses->clear(); + foreach ($addresses as $address) { + $this->addAddress($address); + } + + return $this; + } + + public function addAddress(Address $address): self + { + if (!$this->addresses->contains($address)) { + $this->addresses->add($address); + } + + return $this; + } + + public function removeAddress(Address $address): self + { + $this->addresses->removeElement($address); + + return $this; } }