ERP-119 : revue validation front clients + évolutions écran client (types d'adresse, 2e email, saisies manuelles, redirection) (#80)
Auto Tag Develop / tag (push) Successful in 7s
Auto Tag Develop / tag (push) Successful in 7s
## Contexte Branche ERP-119 — revue de la validation des formulaires clients (déclencheur : écran « Ajouter un client »), accompagnée de plusieurs évolutions de l'écran client (M1). ## Contenu ### Validation front (clients) - Boutons « Valider » toujours actifs (retrait du gating de validité) : c'est le back qui renvoie les 422, mappées en rouge par champ. - Champs requis adossés à une colonne non-nullable : la clé est omise du payload si vide (companyName, RIB, adresse) → 422 NotBlank au lieu d'un 400 de type. - Onglet Contact : au moins un contact requis (l'amorce vide est soumise → 422 RG-1.05). - Onglet Adresse : affichage inline des erreurs type / sites / catégories + RG back « au moins un type d'adresse obligatoire ». ### Nouveaux types d'adresse - Courtier / Distributeur, types autonomes exclusifs : colonnes `is_broker` / `is_distributor` (migration + CHECK miroir d'exclusivité), entité + Callback, et front (select, drapeaux, payloads). ### Saisies manuelles - Adresse : `allow-create` sur le champ Adresse → saisie libre si la BAN ne propose rien. - Date de création : `MalioDate :editable` → saisie clavier JJ/MM/AAAA en plus du calendrier. ### 2e email de facturation - Colonne `billing_email_secondary` (optionnel, max 2), miroir du téléphone secondaire. Bump `@malio/layer-ui` 1.7.8 (prop `addable`). ### Fin d'ajout d'un client - Redirection vers la liste à la validation du dernier onglet remplissable par le rôle (Adresse pour Bureau/Commerciale, Comptabilité pour Admin) + toast « Client ajouté ». Dérivé de `tabKeys`, sans règle RBAC custom. ## Vérifications - Back : suites Module/Commercial + Architecture vertes (Client : 124/124). Migrations appliquées (dev + test). - Front : Vitest vert (272), ESLint OK. > Note : le hook pré-commit flake aléatoirement (JWT 401 / timeout DB) sur des tests sans rapport (Supplier) ; les commits ont été faits après vérification des suites concernées en isolation. Reviewed-on: #80 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #80.
This commit is contained in:
@@ -89,10 +89,7 @@ final class ClientSubResourceApiTest extends AbstractCommercialApiTestCase
|
||||
]);
|
||||
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
$byPath = [];
|
||||
foreach ($response->toArray(false)['violations'] ?? [] as $v) {
|
||||
$byPath[$v['propertyPath']] = $v['message'];
|
||||
}
|
||||
$byPath = $this->violationsByPath($response->toArray(false));
|
||||
|
||||
self::assertArrayHasKey('email', $byPath, 'La violation email doit porter propertyPath=email (mapping front).');
|
||||
self::assertSame('L\'adresse email n\'est pas valide.', $byPath['email']);
|
||||
@@ -135,10 +132,7 @@ final class ClientSubResourceApiTest extends AbstractCommercialApiTestCase
|
||||
]);
|
||||
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
$byPath = [];
|
||||
foreach ($response->toArray(false)['violations'] ?? [] as $v) {
|
||||
$byPath[$v['propertyPath']] = $v['message'];
|
||||
}
|
||||
$byPath = $this->violationsByPath($response->toArray(false));
|
||||
self::assertArrayHasKey('email', $byPath);
|
||||
self::assertSame('L\'adresse email n\'est pas valide.', $byPath['email']);
|
||||
}
|
||||
@@ -237,6 +231,7 @@ final class ClientSubResourceApiTest extends AbstractCommercialApiTestCase
|
||||
$client->request('POST', '/api/clients/'.$seed->getId().'/addresses', [
|
||||
'headers' => ['Content-Type' => self::LD],
|
||||
'json' => [
|
||||
'isDelivery' => true,
|
||||
'postalCode' => '86100',
|
||||
'city' => 'Châtellerault',
|
||||
'street' => '1 rue du Test',
|
||||
@@ -258,6 +253,7 @@ final class ClientSubResourceApiTest extends AbstractCommercialApiTestCase
|
||||
$client->request('POST', '/api/clients/'.$seed->getId().'/addresses', [
|
||||
'headers' => ['Content-Type' => self::LD],
|
||||
'json' => [
|
||||
'isDelivery' => true,
|
||||
'postalCode' => '123',
|
||||
'city' => 'Châtellerault',
|
||||
'street' => '1 rue du Test',
|
||||
@@ -287,6 +283,7 @@ final class ClientSubResourceApiTest extends AbstractCommercialApiTestCase
|
||||
$client->request('POST', '/api/clients/'.$seed->getId().'/addresses', [
|
||||
'headers' => ['Content-Type' => self::LD, 'Accept' => self::LD],
|
||||
'json' => [
|
||||
'isDelivery' => true,
|
||||
'postalCode' => '75001',
|
||||
'city' => 'Paris',
|
||||
'street' => '2 rue Neuve',
|
||||
@@ -313,6 +310,7 @@ final class ClientSubResourceApiTest extends AbstractCommercialApiTestCase
|
||||
$client->request('POST', '/api/clients/999999/addresses', [
|
||||
'headers' => ['Content-Type' => self::LD, 'Accept' => self::LD],
|
||||
'json' => [
|
||||
'isDelivery' => true,
|
||||
'postalCode' => '75001',
|
||||
'city' => 'Paris',
|
||||
'street' => '2 rue Neuve',
|
||||
@@ -382,10 +380,7 @@ final class ClientSubResourceApiTest extends AbstractCommercialApiTestCase
|
||||
]);
|
||||
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
$byPath = [];
|
||||
foreach ($response->toArray(false)['violations'] ?? [] as $v) {
|
||||
$byPath[$v['propertyPath']] = $v['message'];
|
||||
}
|
||||
$byPath = $this->violationsByPath($response->toArray(false));
|
||||
|
||||
self::assertArrayHasKey('bic', $byPath, 'Le mismatch pays BIC/IBAN doit porter propertyPath=bic (mapping front).');
|
||||
self::assertSame('Le BIC ne correspond pas au pays de l\'IBAN.', $byPath['bic']);
|
||||
|
||||
Reference in New Issue
Block a user