feat(commercial) : export XLSX fournisseurs (SupplierExportController, SIREN gaté accounting.view) (ERP-91)
Export XLSX du répertoire fournisseurs (spec § 4.6), jumeau de l'export client M1.
- SupplierExportController avec #[Route(priority: 1)] (anti-conflit API Platform {id}),
is_granted('commercial.suppliers.view'). Mêmes filtres que la liste
(includeArchived/archivedOnly/search/categoryCode/siteId) via createListQueryBuilder()
partagé avec le SupplierProvider ; non archivés par défaut.
- Colonnes : Nom, Contact principal (SupplierContact de plus petit position — ERP-106),
Tél principal/secondaire, Email, Catégories (CSV), Sites (CSV), SIREN (omis sans
accounting.view), Date de création.
- hydrateContacts() ajouté au repository (chargement batché des contacts en une requête
IN, anti-N+1) — méthode dédiée à l'export, la liste paginée n'embarque pas les contacts.
- Tables supplier* ajoutées à ColumnCommentsCatalog : leurs COMMENT (posés par la
migration ERP-85) étaient dropés par le schema:update --force du test-db-setup et non
restaurés, cassant ColumnsHaveSqlCommentTest dès un re-setup de la base de test.
- Test fonctionnel SupplierExportControllerTest (9 cas).
This commit is contained in:
@@ -102,6 +102,31 @@ class DoctrineSupplierRepository extends ServiceEntityRepository implements Supp
|
||||
;
|
||||
}
|
||||
|
||||
public function hydrateContacts(array $suppliers): void
|
||||
{
|
||||
$ids = [];
|
||||
foreach ($suppliers as $supplier) {
|
||||
$id = $supplier->getId();
|
||||
if (null !== $id) {
|
||||
$ids[] = $id;
|
||||
}
|
||||
}
|
||||
if ([] === $ids) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Une seule requete IN bornee : remplit la collection `contacts` des MEMES
|
||||
// instances Supplier (identity map). Tri par position pour que le « contact
|
||||
// principal » (plus petit position) soit deterministe a l'export (§ 4.6).
|
||||
$this->createQueryBuilder('s')
|
||||
->leftJoin('s.contacts', 'sc')->addSelect('sc')
|
||||
->where('s.id IN (:ids)')->setParameter('ids', $ids)
|
||||
->orderBy('sc.position', 'ASC')
|
||||
->getQuery()
|
||||
->getResult()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recherche fuzzy insensible a la casse sur companyName ET sur les contacts
|
||||
* lies (firstName / lastName / email) — decision D1, refonte-contact (§ 4.1).
|
||||
|
||||
Reference in New Issue
Block a user