---
suivi: 1128
date: 2026-07-31
sujet: Diagnostic — parcelle acquise (clôture détentions, fiche, filiation D21)
chantier: module-foncier
type: diagnostic
statut: déployé
hash:
fichiers:
  - tools/diag/diag_parcelle_acquise_1128.php
  - docs/suivi/SUIVI_1128_diag_parcelle_acquise_filiation.md
  - app/Services/Foncier/ActeAcquisitionService.php
  - resources/js/Pages/Foncier/Parcelles/Show.vue
---

## PROMPT ENVOYÉ

SUIVI #1128 — PHASE 1 DIAGNOSTIC : la parcelle acquise (clôture, fiche, filiation).
Trois sujets A/B/C, un rapport. Aucune correction, aucune migration. Fiche + script
diag. Distinguer BUG vs ÉVOLUTION partout.

## SYNTHÈSE

---

# Section A — BUG : détentions non clôturées à l’affichage

### Type : **BUG** (à corriger vite) — cause principale = AFFICHAGE

Le symptôme (3 propriétaires + bouton Retirer chacun sur A 1012 après acte HECTARE)
est **reproductible en code même si R5 a correctement clôturé le pivot** : la fiche
charge **toutes** les lignes `parcelle_proprietaire`, n’expose pas `date_fin_detention`,
et affiche Retirer sur chaque ligne.

La **confirmation données** (anciens à NULL vs datés) reste à coller depuis la prod
via `php tools/diag/diag_parcelle_acquise_1128.php A 1012`.

### A1 — SELECT pivot (à coller depuis prod)

Script : `tools/diag/diag_parcelle_acquise_1128.php`  
Colonnes : `date_debut_detention`, `date_fin_detention`, `acte_foncier_id`,
`detention_courante` (#1096), + identité propriétaire.

Interprétation :

| Résultat A2 | Cause | Correctif données |
|-------------|-------|-------------------|
| 1 courante (HECTARE) + 2 historiques datés | **Affichage seul** | Non |
| ≥2 courantes (fin NULL) dont vendeurs | **Clôture non effective** ou **ré-attach manuel** | Oui (script réparation) |
| Mix | Les deux | Selon lignes |

`pp_courante_uq` (#1096) : UNIQUE(parcelle_id, proprietaire_id, detention_courante).
N’interdit **pas** plusieurs propriétaires **différents** en courante (indivision).
Ne pouvait pas empêcher Robin + ROBINOU + HECTARE simultanés.

### A2 — `ActeAcquisitionService` : clôture implémentée

Fichier `app/Services/Foncier/ActeAcquisitionService.php` (transaction unique) :

1. Créer `actes_fonciers` + `acte_parcelle`
2. Find-or-create propriétaire groupe via `entite_id` (R7)
3. **R5** : `UPDATE parcelle_proprietaire SET date_fin_detention = date_acte
   WHERE parcelle_id IN (…) AND date_fin_detention IS NULL`
4. INSERT détention HECTARE (`date_debut = date_acte`, `date_fin = NULL`,
   `acte_foncier_id`)
5. `parcelles.etat_foncier = acquise`

Conditions de saut : **aucune** dans ce service — tout ou rien (rollback).
Peut être « sauté » seulement si :

- l’acte n’est **pas** passé par ce service (chemin inexistant aujourd’hui —
  `ActeFoncierController` délègue à `creer`) ;
- **après** l’acte, un `attachProprietaire` / création inline a **réouvert** une
  détention courante pour un vendeur (indivision artificielle) ;
- bug données antérieur / import hors service.

Tests Feature (`FoncierPatrimoineVueTest`, `FoncierRattacherParcellesExistantesTest`)
affirment la clôture (`date_fin_detention` = date acte).

### A3 — `Parcelles/Show.vue` : pas de filtre courant

| Couche | Comportement |
|--------|--------------|
| `ParcelleController::show` | `load('proprietaires')` — **toutes** les lignes pivot |
| `serializeProprietairesPivot` | id, label, type, quote_part — **pas** de dates pivot |
| Show.vue bloc Propriétaires | `v-for="p in parcelle.proprietaires"` + Retirer si `peut_gestion` |
| Relation `proprietairesActuels()` | Existe sur le modèle (#1092) — **non utilisée** sur Show |

#1092 Lot A = socle actes + pivot temporel. Le « détenteur actuel vs historique »
annoncé pour un lot B **n’a jamais été livré** sur la fiche parcelle (#1093 = autre
sujet programmes).

### A4 — Bouton « Retirer » — risque

`ParcelleController::detachProprietaire` :

```
DELETE FROM parcelle_proprietaire
 WHERE parcelle_id = ? AND proprietaire_id = ?
   AND date_fin_detention IS NULL
```

| Cas données | Effet Retirer sur un « vendeur » affiché |
|-------------|------------------------------------------|
| Vendeur déjà **clôturé** (fin datée) | DELETE 0 ligne — **no-op** (historique intact) |
| Vendeur encore **courant** (fin NULL) | **DELETE hard** de la ligne courante — **pas** de clôture datée → **perte de trace** de la détention ouverte |

Donc : si les données sont saines, Retirer sur historique est inoffensif mais trompeur.
Si les données sont sales (fin NULL), Retirer **efface** sans historiser — risque grave.
Retirer sur HECTARE courant = suppression de la détention groupe (pas une cession).

### A5 — Autres écrans : filtrent-ils le courant ?

| Écran / conso | Filtre courant ? | Commentaire |
|---------------|------------------|-------------|
| Fiche parcelle Show (#1128) | **NON** | Bug UI |
| Liste prospection (`ParcelleProspectionQuery`) | **NON** | `with`/`withCount('proprietaires')` = toutes lignes ; compte / charges faussés après acquis |
| Dossier #1111 porte propriétaires | N/A pivot dossier | Liste `dossier_foncier_proprietaire` (pas le pivot parcelle) |
| Parcelles dérivées dossier | **OUI** | `parcellesActuelles` + `proprietairesActuels` |
| Offre périmètre #1102 | **OUI** (candidats) | Détentions courantes des propriétaires du dossier |
| Sélecteur parcelles acte (`searchParcelles`) | **OUI** | `proprietairesActuels` pour labels |
| Vue Patrimoine #1120 | **OUI** | `proprietairesActuels` + type `societe_groupe` + `entite_id` ; `statut_cadastral=active` |

**Patrimoine** : n’affiche **pas** une réalité fausse du type « Robin détient » — il
ne garde que les détenteurs **groupe** courants. Si R5 a clôturé, HECTARE seul → OK.
Si vendeurs restés courants **en plus** de HECTARE, la parcelle apparaît quand même
(via HECTARE) ; le faux est surtout sur Show + compteurs prospection, pas un inventaire
patrimoine « vendeur ».

### Fix chiffré A (NON APPLIQUÉ)

| # | Nature | Contenu | Charge | Priorité |
|---|--------|---------|--------|----------|
| A-fix-1 | **BUG** | Show : charger / sérialiser `proprietairesActuels` ; bloc « Détenteurs actuels » ; bloc « Historique » lecture seule (dates début/fin, acte) ; Retirer **uniquement** sur courant | 0,5–1 j | **P0** |
| A-fix-2 | **BUG** | Prospection : `withCount` / eager `proprietairesActuels` (ou wherePivotNull) pour nb + charges | 0,25 j | P1 |
| A-data | **BUG** si A2 prod = NULL | Script réparation : clôturer à `date_acte` les courantes hors acquéreur groupe sur parcelles `acquise` liées à un acte | 0,25–0,5 j | P0 si confirmé |
| A-evo | **ÉVOLUTION** | Remplacer DELETE hard par clôture (`date_fin = today`) + interdire attach manuel si `etat=acquise` (voir B) | 0,5 j | Après cadrage Robin |

---

# Section B — Une parcelle acquise change de nature

### Type : surtout **ÉVOLUTION** (cadrer avec Robin) ; quelques garde-fous = bug UX

### B6 — Inventaire actions fiche vs sens si `acquise`

| Action actuelle | Sens si acquise ? | Classement |
|-----------------|-------------------|------------|
| Inline section / numéro cadastral | Non (identité cadastrale figée jusqu’à division D21) | **ÉVOLUTION** : désactiver + message |
| Inline état foncier (select libre) | Dangereux (bypass acte / cession) | **ÉVOLUTION** : lecture seule ou transitions contrôlées |
| Rattacher / créer / Retirer propriétaire | Non (propriété = **acte**) | **ÉVOLUTION** : désactiver + message ; Retirer courant = bug métier |
| Surfaces cadastrale / arpentée, date arpentage | Oui (évolution post-achat) | OK |
| Zonage PLU, constructible, risque, lieu-dit, commentaire | Oui | OK |
| Occupations (#1119) | Oui | OK |
| Géométrie IGN / manuel | Oui (jusqu’à division) | OK |
| Documents entité (#1117) | Oui | OK |
| Commentaires / historique audit (#1107) | Oui | OK |
| Lien dossiers / actes liés | Oui | OK (à enrichir) |

`statut_cadastral` déjà non inline (whitelist #1107) — affiché lecture seule.

### B7 — Manque sur une fiche acquise

Déjà partiel : bloc « Actes d’acquisition » (réf, date, prix si `foncier.prix`).

Manque :

- société détentrice (libellé entité / propriétaire groupe)
- durée de détention (depuis `date_debut` pivot ou `date_acte`)
- prix mis en avant (pas seulement dans la liste d’actes)
- à terme : valorisations / charges de portage (Phase 1 bis — hors scope)

### B8 — Réversibilité (D14/D26) — **ÉVOLUTION**

États existants (`FoncierReferentiels::ETATS_FONCIERS`) : reperee → … → acquise →
affectee → pas_d_action / projet_abandonne. **Pas** d’état `cedee` / `revendue`.

Mécanisme de cession aujourd’hui : **AUCUN** (pas d’`ActeCessionService`).
Contournement dangereux : changer `etat_foncier` à la main (inline) **sans** clôturer
HECTARE ni créer le nouveau détenteur.

Minimum pour sortir de `acquise` sans cul-de-sac :

1. **Acte de cession** (ou type d’acte étendu) : clôture détention groupe à date,
   ouvre détention acquéreur (tiers), bascule `etat_foncier` (ex. hors patrimoine /
   `pas_d_action` / nouveau code `cedee` — **à trancher avec Robin**) ;
2. Interdire le changement manuel d’état depuis `acquise` hors cet acte ;
3. Patrimoine (#1120) reste dérivé des détentions courantes groupe → cohérent dès
   que la clôture est faite.

### B9 — Organisation proposée de la fiche selon l’état

**Mise en avant si `acquise` (et détention groupe courante)**

1. Bandeau patrimoine : société détentrice, date/durée, lien acte, prix (`foncier.prix`)
2. Identification cadastrale **lecture seule** (section, numéro, statut cadastral)
3. Occupation / PLU / surfaces / géométrie — éditables
4. Historique des détentions (lecture)
5. Documents, dossiers, audit

**Désactivé avec message explicatif (jamais masqué)**

- « Rattacher / créer / retirer un propriétaire » → *La propriété se modifie par un
  acte d’acquisition ou de cession, pas par déclaration.*
- Édition section/numéro → *Identifiant cadastral figé ; une division crée de nouvelles
  parcelles (filiation).*
- Changement libre d’état foncier depuis `acquise` → *Utiliser un acte de cession /
  affectation.*

**Si `reperee` / négociation / compromis** : comportement actuel (prospection).

---

# Section C — Cadrage filiation cadastrale (D21) — **ÉVOLUTION**

### C10 — Règles CDC rappelées vs schéma actuel

| Règle | Contenu | Schéma actuel |
|-------|---------|---------------|
| D21 graphe | Table `(source, issue, type, date, réf DA)` — **pas** `parcelle_mere_id` | **ABSENT** — aucune table filiation |
| Remplacement | Mère `statut_cadastral = remplacee`, jamais DELETE | Colonne **existe** (#1074) ; valeur `remplacee` ; **jamais écrite** par un flux métier |
| D22 surfaces | Σ filles ≠ mère OK ; écart affiché non bloquant | Surfaces indépendantes ; pas de contrôle Σ |
| D23 / D18 | Pas de répartition auto du prix d’achat ; imputation saisie à l’affectation | Prix sur `actes_fonciers` global ; pas d’affectation programme (Phase 3) |

### C11 — Points d’impact (non résolus)

| Sujet | Question ouverte | Note technique |
|-------|------------------|----------------|
| Prospection / patrimoine | `remplacee` doit disparaître des listes actives ? | Prospection + Patrimoine filtrent déjà `statut_cadastral = active` → mère remplacée **sortie** dès le flag ; rester accessible via fiche directe / historique / graphe |
| Détention | Filles héritent du détenteur courant ? | Pivot **par parcelle** → **propagation obligatoire** à la division (clôturer mère ? ou laisser mère remplacée avec détention figée + ouvrir filles) — **à trancher** |
| Géométrie #1109 | Filles = polygones IGN propres | 1:1 `parcelle_geometries` ; réimport IGN par fille ; mère conserve son polygone historique |
| Documents #1117 | Morph `entity_documents` | Rester sur la mère ; option « visible depuis filles » = ÉVOLUTION ultérieure |
| Occupation #1119 | Par parcelle | Décider : clôturer sur mère / recopier / resaisir |
| Audit #1107 | Par modèle | Historique mère intact ; filles démarrent vierges |
| Affectation Phase 3 | Reporter affectations mère → filles ; rien de pendante sur `remplacee` | **Noter seulement** — pas de code maintenant |

### C12 — Découpage lots filiation (sans prompts)

| Lot | Livre | Dépend de |
|-----|-------|-----------|
| F1 — Socle graphe | Table `parcelle_filiations` (source_id, issue_id, type, date, ref_da) + modèle + contraintes ; écriture `statut_cadastral=remplacee` sur sources ; UI lecture graphe sur fiche | Rien (socle) |
| F2 — Opération division / réunion | Formulaire métier (sélection sources, création issues, type, date, DA) ; contrôles surface D22 informatifs ; pas de prix | F1 |
| F3 — Propagation détention | À la division : ouvrir détentions courantes sur filles (même détenteur / acte lien) ; politique mère (figer / clôturer) | F1 + A-fix (détention saine) |
| F4 — Géométries filles | Parcours import IGN multi-filles ; mère inchangée | F2 |
| F5 — Affectations (Phase 3) | Report affectations + garde `remplacee` sans affectation pendante | F2 + chantier affectations |

Ordre conseillé : **A-fix (détentions)** → **B (fiche acquise)** → **F1–F3** → F4 → F5 avec Phase 3.

---

## Matrice BUG vs ÉVOLUTION

| Sujet | Classe |
|-------|--------|
| Show affiche tous les propriétaires + Retirer | **BUG P0** |
| Compteurs / charges prospection sur pivot complet | **BUG P1** |
| Données fin NULL post-acte (si confirmé prod) | **BUG P0 data** |
| Interdire attach manuel / cadastre sur acquise | **ÉVOLUTION** |
| Acte de cession / sortie d’acquise | **ÉVOLUTION** |
| Enrichir bandeau patrimoine sur fiche | **ÉVOLUTION** |
| Filiation D21 | **ÉVOLUTION** (cadrage seul ici) |

## DÉPLOIEMENT / TEST

Diagnostic uniquement.

```
php tools/diag/diag_parcelle_acquise_1128.php A 1012
```

Coller A0–A4 (surtout A2 verdict données) dans le ticket #1128 avant le lot A-fix.

## LEÇON

Historiser le pivot (#1092) sans brancher l’UI sur `proprietairesActuels` laisse
croire que la clôture R5 a échoué. Toujours livrer **données temporelles + filtre
courant + sérialisation des dates** dans le même lot que l’acte — sinon le symptôme
métier (vendeurs encore « Retirer ») survit à un back correct. `pp_courante_uq`
protège le couple, pas l’indivision multi-vendeurs.
