---
suivi: 1598
date: 2026-09-17
sujet: Fix variable non définie serializeAvenants
chantier: foncier / promesses
type: hotfix
statut: poussé
hash: 6b736ea6
fichiers:
  - app/Http/Controllers/Foncier/PromesseFonciereController.php
  - tests/Unit/Promesse1598LectureCorbeilleSourceTest.php
  - docs/suivi/SUIVI_1598_fix_variable_non_definie_promesses.md
---

# SUIVI #1598 — Undefined variable $lectureCorbeille

## PROMPT ENVOYÉ

500 onglet PROMESSES dossier 97. Log : Undefined variable
`$lectureCorbeille` à PromesseFonciereController.php:706.
Corriger tous les chemins. Revoir les lots #1589–#1597.
Proposer un contrôle statique, ne pas l’installer.

## FICHES LUES

- **#1593 LEÇON** — corbeille promesse, lecture via `showCorbeille`
  → `renderShow(..., true)`. Impact : `$lectureCorbeille` ajoutée
  au payload documents/avenants, mais oubliée dans le `use` de la
  closure `serializeAvenants`.

## CAUSE EXACTE

`$lectureCorbeille` **était définie** :

| Lieu | Rôle |
|---|---|
| `renderShow(..., bool $lectureCorbeille = false)` | paramètre, défaut `false` |
| `show` / `showDirect` | appellent `renderShow` **sans** 4ᵉ arg → `false` (fiche vivante) |
| `showCorbeille` | `renderShow(..., true)` |
| `serializeAvenants(..., bool $lectureCorbeille = false)` | paramètre, défaut `false` |
| L.518 | `serializeAvenants($promesse, $peutPrix, $user, $lectureCorbeille)` — **passé** |

Chemin fautif : la closure `map` (ancienne L.691) faisait
`use ($peutPrix, $user, $promesse)` **sans** `$lectureCorbeille`.
En PHP une closure n’hérite pas la portée parente. Dès qu’une
promesse a **au moins un avenant**, le callback s’exécute et
évalue `! $lectureCorbeille` → 500. Sans avenant, `map` ne
rentre pas dans le callback : pas d’erreur.

L’URL `/foncier/dossiers/97?onglet=promesses` construit la liste
via `DossierFoncierController::serializePromesseListe` (pas
`serializeAvenants`). Le 500 L.706 est la **fiche** promesse
(`show` / `showDirect` / `showCorbeille`) ouverte depuis l’onglet
(`:href="/foncier/promesses-foncieres/{id}"`).

Défaut correct : `false` (consultation normale ≠ corbeille).

Correctif : ajouter `$lectureCorbeille` au `use` de la closure.

## REVUE LOTS DU JOUR (#1589–#1597)

Fichiers lus / greppés (`function (…) use (`, `$lectureCorbeille`) :

| Fichier | Résultat |
|---|---|
| `PromesseFonciereController` | **seul trou** : closure `serializeAvenants`. Autres `use` (`$today`, `$peutPrix`, `$p`, `$like`) complets. |
| `DossierFoncierController` | `$lectureCorbeille` paramètre de `showInertiaProps` / `documentsPayloadPourShow` / `tachesSuiviPourDossier` avec défaut ; usages dans le corps, pas une closure orpheline. |
| `DossierFoncierCorbeilleController` | `showInertiaProps(..., true)` ; `through` capture `$quiParPromesse`. |
| `PromesseAvenantController` | pas de `$lectureCorbeille` ; closures `use` des services OK. |
| `ConditionSuspensiveController` | pas de closure, pas de `$lectureCorbeille`. |
| `PromesseFonciereService` / `PromesseAvenantService` / `ConditionSuspensiveService` / `DossierFoncierCorbeilleService` | `use` des transactions complets (variables locales dans le corps, pas un oubli). |
| `DossierProgrammeLink` / `DossierFoncier` (#1597) | pas de closure `use` orpheline. |
| `ProgrammeController` | `use` des closures index/store/update complets. |

Aucun autre cas du même type trouvé. Rien d’autre corrigé.

## CONTRÔLE STATIQUE (proposition, PAS installé)

`php -l` et `ReflectionClass` ne voient pas une variable absente
d’un `use` de closure.

Disponible dans le projet : PHPUnit, Pint. **Pas** de PHPStan /
Larastan / Psalm (`composer.json` require-dev).

Candidat : **Larastan** (`nunomaduro/larastan`, PHPStan) niveau 0 ou 1,
règle `variable.undefined`. Ça aurait attrapé L.706.

Coût approximatif :
- `composer require --dev larastan/larastan` (paquet actuel) ;
- un `phpstan.neon` (level 0 d’abord) ;
- première passe **bruyante** sur un ERP Laravel de cette taille
  (baseline à constituer, plusieurs heures) ;
- ensuite : une commande locale + éventuellement CI, quelques
  minutes par lot.

Contrôle plus léger, déjà dans ce lot : test source du `use` +
invocation réelle de `serializeAvenants` via Reflection (collection
en mémoire, sans DB) — ça échoue si la variable n’est plus capturée.

Robin arbitre l’installation Larastan plus tard.

## DÉPLOIEMENT

```
git pull origin main
php artisan optimize:clear
php artisan view:clear
```

Pas de migrate. Pas de journal:sync. Pas de route:clear. Pas de Vite.

## LEÇON

Une variable définie en paramètre de méthode n’existe pas dans une
closure PHP tant qu’elle n’est pas dans `use`. Tester le chemin qui
**entre** dans le `map` (ici : promesse **avec** avenant). `php -l`
ne suffit pas.
