---
suivi: 1496
date: 2026-09-10
sujet: Harmonisation filtre société f_societe CSV
chantier: comptabilite / filtres
type: fix
statut: poussé
hash: 98f545ff
fichiers:
  - app/Support/QueryIdListParser.php
  - app/Support/SocieteEntiteResolver.php
  - app/Support/ComptabilisationListeFilter.php
  - app/Support/PaiementLignesFiltre.php
  - app/Http/Controllers/ComptabilisationController.php
  - app/Http/Controllers/PaiementController.php
  - app/Services/FactureGlobaleListeQuery.php
  - tests/Unit/QueryIdListParserTest.php
  - tests/Unit/HarmonisationFiltreSociete1496SourceTest.php
  - tests/Unit/HarmonisationFiltreSociete1496Test.php
  - tests/Unit/SocieteEntiteResolverTest.php
  - tests/Unit/PaiementLignesFiltreTest.php
  - tests/Feature/HarmonisationFiltreSociete1496FeatureTest.php
  - docs/suivi/SUIVI_1496_harmonisation_filtre_societe.md
---

# SUIVI #1496 — Harmonisation `f_societe` CSV

## PROMPT ENVOYÉ

Le #1495 s’est arrêté (clause 2) : trois écrans, trois conventions pour
le filtre société. Harmoniser sur `f_societe` CSV comme la liste globale.
Aucune UI de filtre nouveau. Tableau de bord = lot suivant. Interdiction
#1495 de toucher ComptabilisationController / ListeFilter LEVÉE, parsing
société uniquement.

## BASE GIT

HEAD attendu `4b96e52b` (fiche #1494). origin/main à jour, pas de rebase.
#1493 non présent sur main ; DepotFactureSaisieForm / DepotFactureController
non touchés.

## FICHES LUES

- **#1495** (arrêt, pas de fiche disque) — trois conventions incompatibles ;
  CSV `f_societe=1,2,3` 422 sur comptabilisation ; `f_societe` ignoré sur
  MEP même en mono. Impact : ce lot n’ajoute aucun filtre, il aligne la
  lecture. Source d’entité = resolver (dépôt OU programme), pas le COALESCE
  bancaire.
- **#1483 LEÇON** — le clic ouvre exactement le périmètre du compteur.
  Impact : sans CSV lisible, le lot tableau de bord recasserait cet acquis.
- **#1478 LEÇON** — totaux socle, droits via m365GroupNames() brut.
  Impact : ComptaTableauBordAcces / FactureVisibility non touchés.

## SYNTHÈSE

Parseur unique `QueryIdListParser` (ex-`parseIdList` de
FactureGlobaleListeQuery, plus l’int de l’ancien `parseEntiteId`).
Comptabilisation : validation `string|max:2000` comme la liste globale ;
ids inexistants ignorés (pas de 422 `exists`). MEP : lit `f_societe` ;
`entite_id` reste l’alias (le select de l’écran l’émet toujours) ;
si les deux sont remplis, `f_societe` gagne. Resolver : `int|array`
rétrocompatible + `applyFiltreEntiteOnQuery` (whereExists, même
périmètre, `programmes.deleted_at` comme whereHas). Sémantique MEP
inchangée (mêmes trois OR, IN au lieu de = dès 2 ids). Aucun bundle.
Pas de journal (geste utilisateur identique). Pas de migration.

## DÉPLOIEMENT-TEST

```
git pull origin main
find app/ config/ database/ -name "*.php" -exec touch {} +
php artisan optimize:clear && php artisan view:clear && php artisan route:clear
```

Pas de migrate. Pas de journal:sync. Pas de npm/composer/optimize sur OVH.

Test manuel **Sabrina (24) ou Rudy** (GS_COMPTABILITE), pas Robin :

1. `/factures/comptabilisation` sans query → liste identique à avant.
2. Choisir une société dans le select → URL `f_societe=N`, même filtre.
3. Coller `?f_societe=ID1,ID2` (deux ids réels) → **pas de 422**, union.
4. `/factures/mise-en-paiement?entite_id=N` (favori existant) → identique.
5. `/factures/mise-en-paiement?f_societe=N` → même périmètre que (4).
6. `/factures/mise-en-paiement?f_societe=ID1,ID2` → union, pas de doublon.
7. `/factures?f_societe=ID1,ID2` → inchangé.
8. 500 : `grep "production.ERROR" storage/logs/laravel.log | tail -20`

## LEÇON

Trois écrans qui nomment le même filtre différemment : l’un 422, l’autre
ignore en silence. Factoriser le parseur **avant** de propager un filtre
depuis un tableau de bord. `exists:entites,id` sur un CSV casse le multi.
`whereHas` et `whereExists` ne sont équivalents que si la dérivée exclut
aussi les programmes soft-deleted.
