---
suivi: 1252
date: 2026-08-07
sujet: Offre foncière — prix et ventilation par propriétaire
chantier: foncier / offres
type: feature
statut: poussé
hash: de5add40
fichiers:
  - database/migrations/2026_08_07_180000_add_proprietaire_id_to_offre_composantes_prix.php
  - app/Models/OffreComposantePrix.php
  - app/Http/Controllers/Foncier/OffreFonciereController.php
  - app/Http/Controllers/Foncier/DossierFoncierController.php
  - resources/js/Components/Foncier/OffreCreateDialog.vue
  - resources/js/Pages/Foncier/Offres/Show.vue
  - docs/suivi/SUIVI_1252_offre_prix_par_proprietaire.md
  - public/build/
note_journal: entrée `offre-prix-par-proprietaire-1252-2026-08-07` déjà présente sur main (commit #1253)
---

# SUIVI #1252 — Prix / ventilation par propriétaire

## PROMPT ENVOYÉ

Descendre la ventilation du prix au propriétaire (pas à la parcelle).
Montants toujours calculés. Pas de reprise des 3 offres / 7 composantes.

## FICHES LUES

- `#1195` — montant = Σ ventilation, modale, dirty-close
- `#1197` — indicateur écart prix dossier (lit `offres_foncieres.montant`)
- `#1126` — table `offre_composantes_prix` / types
- `#1247` — DDL rejouable, bindings
- `#1249` / `#1250` / `#1251` — a priori disjoints (parcelles / Marches) ; rebase sur `origin/main` à jour

## SCHÉMA VÉRIFIÉ

| Table | Colonnes pertinentes |
|---|---|
| `offre_composantes_prix` | id, offre_fonciere_id, type_composante_id, libelle_libre, montant, commentaire (+ **proprietaire_id** nullable) |
| `offre_proprietaire` | offre_fonciere_id, proprietaire_id |
| `offres_foncieres` | montant (calculé / conservé) |
| `types_composantes_prix` | code, libelle, ordre |

Rattachement : FK `offre_comp_proprio_fk` → `proprietaires.id` (nullOnDelete), index `offre_comp_proprio_idx`.

## COMPORTEMENT DÉCOCHAGE

Ventilation **conservée en mémoire** dans la modale (`composantesByProprio`), **exclue du total**, signal
« Ventilation saisie — exclue du total (propriétaire décoché) ». À l’enregistrement,
seuls les destinataires cochés envoient leurs composantes.

## CONSOMMATEURS DU MONTANT

| Consommateur | Fichier:ligne | Changement |
|---|---|---|
| Indicateur écart dossier | `DossierFoncierController.php` ~1785 (`derniere_offre_montant`) | Aucun : lit `offres_foncieres.montant` (= Σ) |
| Liste négociations dossier | idem serialize ~1723–1744 | Composantes enrichies `proprietaire_id` / `proprietaire_label` si `foncier.prix` |
| Fiche offre + ventilation | `OffreFonciereController.php` serialize ~1246+ | + `montants_par_proprietaire` ; edit ventilation par proprio |
| Duplication | `dupliquer` | copie aussi `proprietaire_id` |
| Audit `ventilation` | `OffreFonciere::sensitiveAuditedFields` + `FieldAuditService` | Snapshot préfixe proprio ; masqué sans `foncier.prix` |
| Statut inline | #1198/#1202 | inchangé |
| Génération compromis (D35) | — | **Proposition ouverte** : préremplir le montant **du propriétaire** de la promesse, pas le global — **non implémenté** |
| Scénarios / exports / Aktor | — | aucun lecteur direct trouvé de la ventilation par proprio |

## PREUVE OFFRES EXISTANTES

Aucune migration de données. `proprietaire_id` NULL sur les 7 lignes.
`offres_foncieres.montant` non touché → totaux identiques avant/après.

## CONFIDENTIALITÉ

Composantes / `montants_par_proprietaire` / audit `ventilation` derrière `foncier.prix`.
Signal : un montant par proprio est plus sensible qu’un global
(cloisonnement supplémentaire éventuel = lot ultérieur).

## MAPPING NATURE

| Libellé affiché | Valeur postée (`type_composante_id`) | Libellé back (`types_composantes_prix.code`) |
|---|---|---|
| Numéraire | id seed | `numeraire` |
| Dation de lots | id | `dation_lots` |
| ODF | id | `odf` |
| Échange de terrain | id | `echange_terrain` |
| Prise en charge VRD | id | `prise_en_charge_vrd` |
| Complément de prix conditionné | id | `complement_prix_conditionne` |
| Rente viagère | id | `rente_viagere` |
| Autre (+ libellé libre) | id | `autre` |

## LEÇON

Descendre un prix au propriétaire sans toucher D23 (pas de répartition parcellaire) :
étendre la table de ventilation existante, nullable, zéro reprise.

## DÉPLOIEMENT

```
git pull origin main
php artisan migrate --force
php artisan migrate:status | grep -c Pending   # → 0
php artisan optimize:clear && php artisan view:clear
php artisan journal:sync
```
