Compare commits

..

3 Commits

Author SHA1 Message Date
gitea-actions 54091be60e chore: bump version to v0.1.89
Auto Tag Develop / tag (push) Successful in 6s
Build & Push Docker Image / build (push) Successful in 18s
2026-06-08 07:36:48 +00:00
matthieu e265a008bc feat(commercial) : validators M2 fournisseurs (RG-2.03/2.07/2.08/2.10) (ERP-89) (#68)
Auto Tag Develop / tag (push) Successful in 7s
Étape 4/7 du M2 fournisseurs — stackée sur #67 (ERP-88).

## Périmètre (RG-2.03 / 2.07 / 2.08 / 2.10)

Décision figée ERP-89 : les RG inter-champs passent par `Assert\Callback` + `->atPath()` sur l'entité Supplier (et non dans le Processor), pour que chaque 422 porte un `propertyPath` consommable par `extractApiViolations` (mapping inline, pas un toast — ERP-101).

- **RG-2.10** — `Supplier::validateCategoryType()` → `atPath('categories')` : catégories de type FOURNISSEUR uniquement sur `supplier.categories` (miroir d'ERP-88 côté adresse).
- **RG-2.07** — `Supplier::validatePaymentTypeConsistency()` → `atPath('bank')` : VIREMENT impose une banque.
- **RG-2.08** — même Callback → `atPath('ribs')` : LCR impose ≥ 1 RIB (le 409 sur DELETE du dernier RIB en LCR reste porté par ERP-88).
- **RG-2.03** — `SupplierInformationCompletenessValidator` (8 champs Information dont `volumeForecast`), invoqué par le `SupplierProcessor` après détection back du rôle Commerciale via `BusinessRoleAwareInterface`. Le Processor ne porte que rôle / mode strict / gating.

## Tests (16, verts)

- `SupplierValidationTest` — Callbacks RG-2.07/2.08/2.10, assertion par propertyPath.
- `SupplierInformationCompletenessValidatorTest` — complétude / champs manquants / zéros valides.
- `SupplierProcessorTest` — détection rôle RG-2.03 (POST + PATCH main-only + non-Commerciale).

`make test` : 499 tests OK. `php-cs-fixer` : clean.

---------

Co-authored-by: admin malio <malio@yuno.malio.fr>
Co-authored-by: Matthieu <contact@malio.fr>
Reviewed-on: #68
Co-authored-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
Co-committed-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
2026-06-08 07:33:38 +00:00
matthieu 145d4362db feat(commercial) : sous-ressources M2 fournisseurs (contacts/adresses/ribs) (ERP-88) (#67)
Auto Tag Develop / tag (push) Successful in 7s
## ERP-88 — Sous-ressources M2 (contacts / adresses / ribs)

Étape 4/7 du pipeline M2. Dépend de #86 (entités) et #87 (Provider/Processor). Bloque #92.

### Contenu
Opérations API Platform + Processors d'écriture des sous-collections du fournisseur (POST/PATCH/DELETE + GET unitaire).

**SupplierContactProcessor**
- Rattachement au fournisseur parent (404 si absent).
- Normalisation serveur RG-2.12 (Title Case nom/prénom, téléphones chiffres seuls, email lowercase).
- RG-2.04 : firstName **ou** lastName obligatoire (422 sur `firstName`).
- DELETE libre (RG-2.13 front-driven : collection peut rester vide côté back).

**SupplierAddressProcessor**
- Rattachement au fournisseur parent.
- RG-2.05 (CP `^[0-9]{4,5}$`), RG-2.06 (≥1 site), RG-2.09 (type d'adresse) portées par les contraintes d'entité (ERP-86).
- RG-2.10 (catégorie de type FOURNISSEUR) ajoutée via `Assert\Callback validateCategoryType` (propertyPath=`categories`).

**SupplierRibProcessor**
- Rattachement au fournisseur parent.
- RG-2.08 : refus du DELETE du dernier RIB quand `paymentType.code = LCR` → **409**.

### Security différenciée
| Sous-ressource | Écriture | Lecture |
|---|---|---|
| contacts / adresses | `commercial.suppliers.manage` | `commercial.suppliers.view` |
| ribs | `commercial.suppliers.accounting.manage` | `commercial.suppliers.accounting.view` |

POST en `read:false` (parent rattaché manuellement) — parade NonUniqueResult héritée du M1. Messages FR (ERP-107) + `violations[].propertyPath` aligné (ERP-101).

### Vérifications
- `make php-cs-fixer-allow-risky` : 0 fichier à corriger
- `make test` : 483 tests OK
- `debug:router` : 12 routes générées (4 par sous-ressource)

### Hors périmètre (tickets suivants)
- Déclaration RBAC `commercial.suppliers.*` dans `CommercialModule` (#7) — sans elle, l'accès reste 403.
- Tests fonctionnels de la matrice RG (#8) — dépendent du RBAC + fixtures Supplier.

### Notes de review (non bloquantes, alignées M1)
- `position` des sous-collections non exposé à l'API (décision ERP-86, géré serveur).
- M2M `SupplierAddress.contacts` non vérifié same-supplier — comportement identique au M1 (ClientAddress), à traiter globalement si besoin.

---------

Co-authored-by: Matthieu <contact@malio.fr>
Reviewed-on: #67
Co-authored-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
Co-committed-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
2026-06-08 07:31:48 +00:00
+1 -1
View File
@@ -1,2 +1,2 @@
parameters:
app.version: '0.1.87'
app.version: '0.1.89'