---
suivi: 1036
date: 2026-07-29
sujet: Correctif filtre Facturé NV1 — source unique PHP+SQL
chantier: budgets-programme
type: fix
statut: poussé
hash: fe50bea7
fichiers:
  - app/Models/DepotFacture.php
  - app/Services/BilanFinancierService.php
  - tools/diag/diag_bilan_1035.php
  - tests/Unit/BilanFiltreNv1SourceUniqueTest.php
  - docs/suivi/SUIVI_1035_bilan_engage_hors_marche.md
---

## PROMPT ENVOYÉ

SUIVI #1036 — correctif de sous-évaluation Facturé après #1035.
Exigence : une seule définition de la règle NV1 validée, partagée entre méthode PHP et agrégations SQL, sans liste de statuts parallèle.

## SYNTHÈSE

- Source unique introduite : `DepotFacture::sqlConditionCompteDansFactureApresNv1Valide()`.
- La méthode objet `compteDansFactureApresNv1Valide()` est alignée sur la même règle :
  - exclusions rejet/archive/rejetée/soft-delete,
  - **saisie_historique préservée** (sans workflow),
  - non historique : `facture_id` obligatoire + `aWorkflowNv1Valide()`.
- `BilanFinancierService` n'itère plus dépôt par dépôt avec logique locale :
  - `buildFactureNv1ByMarche()` utilise la condition SQL canonique,
  - `buildDepotsHorsMarcheKpiParPoste()` utilise la même condition SQL canonique.
- `DepotFacture::sommeMontantHtFactureApresNv1PourProgramme()` est également branchée sur cette même condition SQL.
- `tools/diag/diag_bilan_1035.php` §2 corrigé : suppression du filtre statuts en dur, utilisation de la condition canonique.

### Audit des appelants

Appelants de `compteDansFactureApresNv1Valide()` et/ou de la règle NV1 :
1. `app/Models/DepotFacture.php` (`sommeMontantHtFactureApresNv1PourProgramme`)  
   → impact : maintenant aligné SQL sur la source unique (plus de fallback par statuts normalisés).
2. `app/Services/BilanFinancierService.php` (`buildFactureNv1ByMarche`, `buildDepotsHorsMarcheKpiParPoste`)  
   → impact : agrégation SQL canonique, inclut les NV1 validées même en `en_validation_nv2`.
3. `app/Http/Controllers/ProgrammeDashboardController.php` (via `sommeMontantHtFactureApresNv1PourProgramme`)  
   → impact : KPI dashboard suit la même règle canonique que le bilan.
4. `tools/diag/diag_bilan_1035.php`  
   → impact : le tableau AVANT/APRÈS §2 reflète enfin la règle canonique (plus de faux delta négatif sur NV2 avec NV1 validée).

### Journal #412

NON ajouté : correctif d’alignement d’une règle existante (#1035 déjà journalisé le même jour), sans nouveau comportement métier visible distinct à communiquer séparément.

## DÉPLOIEMENT-TEST

1. `git pull origin main`
2. `find app/ -name "*.php" -exec touch {} +`
3. `php artisan view:clear`
4. `php tools/diag/diag_bilan_1035.php`
   - §0 : 0 ligne overlap
   - §1 : bouclage axe marché + axe enveloppe
   - §2 : delta programme 1 ne doit plus montrer le -100€ lié au cas NV2+NV1 validée

## LEÇON

Même quand le code applicatif est correct, un script de contrôle parallèle avec une règle simplifiée peut induire une mauvaise conclusion de prod. Sur les règles sensibles (NV1/NV2), centraliser l’expression SQL et imposer sa réutilisation partout évite les dérives silencieuses.
