Matthieu
f8f7571cc0
feat(field_sales) : calcul de trajet, optimisation, duplication & roadbook PDF (ERP-125)
...
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Failing after 52s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Failing after 11s
- RouteEngineInterface (computeMatrix/optimizeOrder/estimateLegDurations) + HaversineRouteEngine V1 (vitesse moyenne parametrable, plus proche voisin)
- TourRouteCalculator : resolution coords, ETA (RG-6.11), exclusion sans coords (RG-6.05), totaux ; optimize = reorder + recompute
- Endpoints API Platform POST /tours/{id}/compute, /optimize, /duplicate (TourDuplicator, RG-6.13) + Processors, security manage
- Feuille de route PDF GET /tours/{id}/roadbook.pdf (Dompdf + Twig) via PdfRendererInterface (Shared), controller priority:1, security view
- TierAddressResolver etendu (coords + location DBAL)
- Tests : HaversineRouteEngine (unit), compute/optimize/duplicate/roadbook (API)
2026-06-11 16:46:49 +02:00
Matthieu
0052eab1fe
feat(field_sales) : entités et API Tournée + Étape (Tour/TourStop) (ERP-124)
...
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Failing after 29m14s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Failing after 11s
Modèle et API CRUD du module Tournées (M6.3, scope réduit V0.2 : pas de
rapport de visite, donc TourStop sans report_id ni check-in).
- Entités Tour (table tour) + TourStop (table tour_stop) : #[Auditable],
Timestampable/Blamable, enum TourStatus (draft|planned|in_progress|done),
soft delete sur Tour.
- API Platform : GET/POST/GET/PATCH/DELETE /api/tours (DELETE = soft delete),
sous-ressource POST /api/tours/{tourId}/stops + PATCH/DELETE /api/tour_stops/{id}.
- RG-6.01 : tournée personnelle (TourProvider filtre owner ; admin/Bureau
voient tout). RG-6.03 : adresse appartient au Tiers (TourStopProcessor +
TierAddressResolver DBAL, sans import inter-module). RG-6.07 : pas d'unicité
tier_id. RG-6.12 : cohérence custom/Tiers (Assert\Callback).
- Migration racine : tables + COMMENT ON COLUMN FR + index unique
(tour_id, position) + FK CASCADE ; mirror dans ColumnCommentsCatalog.
- i18n audit (fieldsales_tour / _tourstop), mappings Doctrine + API Platform.
- Tests fonctionnels : owner, RG-6.03/6.07/6.12, pagination, unicité position,
soft delete, RBAC (17 tests).
Co-Authored-By: Matthieu <mtholot19@gmail.com >
2026-06-11 15:54:10 +02:00
Matthieu
be9204eca7
feat(field_sales) : fondations du module Tournées + VisitableInterface + RBAC (ERP-123)
...
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 2m26s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Failing after 13s
- Module FieldSales (ID field_sales, REQUIRED false) avec 2 permissions
field_sales.tours.view / .manage (scope V0.2, pas de reports.*), active
dans config/modules.php.
- Contrat partage VisitableInterface (getId/getDisplayName/getVisitableType)
implemente par Client (client) et Supplier (supplier) sans import inter-module.
Note doctrine.yaml : contrat polymorphe (2 implementations) donc resolu par
service via (tier_type, tier_id), pas via resolve_target_entities.
- 3 miroirs RBAC alignes : sidebar.php (section Tournées, item /tours, i18n
sidebar.field_sales.*), personas.ts et SeedE2ECommand.php (user-full) ;
matrice metier RbacSeeder (Commerciale = view+manage, Bureau = view, Compta
exclue, Admin bypass).
2026-06-11 14:51:52 +02:00