Files
Starseed/src/Module/Commercial/Domain/Repository/ClientRepositoryInterface.php
T
tristan fbfb77f7a4
Auto Tag Develop / tag (push) Successful in 12s
tags multiselect — couleur des sites + limite d'affichage (#161)
## Objectif

Améliorer les multiselects (`MalioSelectCheckbox`) de l'application :

### Couleur des sites sur les tags
Les tags des multiselects **sites** (86 / 17 / 82) prennent désormais :
- en **fond** la couleur d'identification du site (champ `color`, groupe `site:read` — déjà exposé côté API, aucune modif back) ;
- en **texte** du blanc, pour rester lisibles sur les fonds colorés.

Appliqué en saisie **et** en consultation, dans les 4 modules concernés : Clients (M1), Fournisseurs (M2), Prestataires (M3), Produits (M6).

### Limite d'affichage des autres multiselects
Tous les multiselects **non-sites** (catégories, contacts, états, types de stockage…) affichent **au maximum 3 tags** ; le surplus est condensé en « +N ».

## Dépendance
- Bump `@malio/layer-ui` `1.7.15` → `1.7.17` (support `color` / `textColor` et `maxTags` sur les options).

## Tests
- 722 tests Vitest verts (69 fichiers), assertions des options sites enrichies (`color` / `textColor`).
- ESLint clean sur les 15 fichiers `.vue` modifiés.

> Commit front-only : hook pre-commit (tests back) contourné via `--no-verify`, la validation front a été lancée séparément.

Reviewed-on: #161
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
2026-06-29 12:16:53 +00:00

74 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Module\Commercial\Domain\Repository;
use App\Module\Commercial\Domain\Entity\Client;
use Doctrine\ORM\QueryBuilder;
interface ClientRepositoryInterface
{
public function findById(int $id): ?Client;
public function save(Client $client): void;
/**
* Construit un QueryBuilder de liste pour le repertoire clients.
* - Exclut toujours les clients soft-deletes (deleted_at IS NOT NULL, RG-1.24).
* - Archivage (RG-1.25) :
* - $archivedOnly = true -> uniquement les archives (is_archived = true) ;
* - sinon $includeArchived = true -> actifs + archives (echappatoire) ;
* - sinon (defaut) -> uniquement les actifs (is_archived = false).
* $archivedOnly a la priorite sur $includeArchived.
* - Tri par defaut : companyName ASC (RG-1.26).
* - $search : recherche fuzzy insensible a la casse sur companyName +
* lastName + email (metacaracteres LIKE echappes). Ignore si null/vide.
* - $categoryCodes : restreint aux clients possedant au moins une categorie
* dont le code est dans la liste (OR — ERP-78). Liste vide = pas de filtre.
* - $siteIds : restreint aux clients ayant au moins une adresse rattachee a
* l'un des sites donnes (OR — RG-1.10). Liste vide = pas de filtre.
* - $excludeCategoryCodes : EXCLUT les clients possedant au moins une
* categorie dont le code est dans la liste (NOT IN). Liste vide = pas de
* filtre. Utilise par le module Transport pour ecarter les courtiers
* (code COURTIER) des selects clients.
*
* Filtrage centralise ICI (et non dans les providers/controllers) pour que
* la liste paginee (ClientProvider) et l'export (ClientExportController)
* partagent strictement la meme logique de selection.
*
* Contrat = SELECTION uniquement (filtres + tri). Aucun fetch-join to-many :
* l'hydratation des collections affichees est une decision de l'appelant
* (cf. {@see self::hydrateListCollections()}), pour ne pas imposer le cout
* d'un produit cartesien a un consommateur qui ne filtrerait/compterait que
* (ERP-100).
*
* @param list<string> $categoryCodes
* @param list<int> $siteIds
* @param list<string> $excludeCategoryCodes
*/
public function createListQueryBuilder(
bool $includeArchived = false,
?string $search = null,
array $categoryCodes = [],
array $siteIds = [],
bool $archivedOnly = false,
array $excludeCategoryCodes = [],
): QueryBuilder;
/**
* Hydrate en lot les collections affichees par le repertoire (categories,
* adresses et leurs sites) sur un jeu de clients DEJA charges, via l'identity
* map Doctrine (memes instances). A appeler apres une selection bornee (page
* courante ou jeu d'export) pour eviter le N+1 a la serialisation, sans
* imposer de fetch-join au QueryBuilder de selection (ERP-100).
*
* Charge les categories et les adresses/sites en DEUX requetes distinctes
* (et non un triple fetch-join) pour ne pas multiplier categories x adresses
* x sites en un seul produit cartesien.
*
* @param list<Client> $clients
*/
public function hydrateListCollections(array $clients): void;
}