---
suivi: 1593
date: 2026-09-17
sujet: Mise en corbeille d’une promesse foncière
chantier: foncier / promesses
type: feature
statut: poussé
hash: 22adb9b7
fichiers:
  - app/Models/PromesseFonciere.php
  - app/Services/Foncier/PromesseFonciereService.php
  - app/Http/Controllers/Foncier/PromesseFonciereController.php
  - app/Http/Controllers/Foncier/DossierFoncierController.php
  - app/Http/Controllers/Foncier/DossierFoncierCorbeilleController.php
  - app/Services/Foncier/DossierFoncierSuiviAggregator.php
  - routes/web.php
  - resources/js/Pages/Foncier/Dossiers/Show.vue
  - resources/js/Pages/Foncier/Dossiers/Corbeille.vue
  - resources/js/Pages/Foncier/Promesses/Show.vue
  - tests/Unit/DossierFoncier1593PromesseCorbeilleSourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
  - docs/suivi/SUIVI_1593_corbeille_promesse.md
---

# SUIVI #1593 — Corbeille d’une promesse

## PROMPT ENVOYÉ

Mise en corbeille d’une promesse (GS_ADMIN_ERP, soft delete, pas
d’effacement). Action sur la ligne et la fiche. Promesse actée
verrouillée (refus UI + serveur). Confirmation nommant les parcelles
qui perdent « Sous compromis ». Recalcul `ParcelleStatutService`
(#1569). Qui / quand + journal dossier. Consultation alignée #1589.

## FICHES LUES

- **#1589 LEÇON** — `deleted_at` déjà sur `promesses` (migration
  `2026_09_17_140000`) ; `chargerFaits` filtre `pr.deleted_at` ;
  consultation via `DossierFoncierCorbeilleDroits` + page Corbeille
  dossiers ; pas de restauration ; documents hors SoftDeletes.
  Impact : **pas de migration**. Pas de second module corbeille :
  section Promesses sur la même page + `showCorbeille` / download
  dédiés (ACL `userPeut`, pas Gate).
- **#1089 / R7** — `verrouillerApresActe` pose `statut = acte` ET
  `verrouille = true`. Impact : le marqueur UI `(verrou)` est
  `pr.verrouille`, pas le statut. Le refus #1593 couvre les deux
  (et un acte encore rattaché).
- **#1569 LEÇON** — `deduire()` : détenue > sous_compromis (promesse
  `signe` via pivot) > offre > dossier_vivant. Impact : on appelle
  `recalculerIds`, on ne change pas `deduire`. `chargerFaits` ignore
  déjà les promesses soft-deleted.
- **#1579 / #1583** — agrégateur lecture. Impact : audit
  `promesse_corbeille` (qui / quand) ; `withTrashed` pour conserver
  l’événement « Promesse signée ».
- **#1592 LEÇON** — ConfirmDialog PrimeVue sur l’onglet FONCIER.
  Impact : même patron sur PROMESSES / fiche promesse (pas
  `window.confirm`).

## VERROU — ÉTABLI AVANT CODE

| Couche | Lieu | Ce que ça recouvre |
|---|---|---|
| Écriture | `PromesseFonciereService::verrouillerApresActe` | `statut = acte` + `verrouille = true` + `date_acte_reelle` |
| Écriture | `assertEcritureAutorisee` / `estVerrouillee()` | colonne `promesses.verrouille` uniquement |
| UI liste | `Show.vue` `(verrou)` | `pr.verrouille` |
| UI fiche | badge « Verrouillée » | prop `verrouille` = `estVerrouillee()` |
| Déverrouillage | `deverrouiller` | `verrouille = false` ; **le statut reste `acte`** |

Une promesse déverrouillée reste actée : le #1593 refuse aussi
`statut === acte` et `actesFonciers()->exists()`, pas seulement
`verrouille`. Motif UI : « Actée — ne peut pas être retirée ».

## SOFT DELETE — PAS DE MIGRATION

`promesses.deleted_at` existe depuis #1589. Pas de `deleted_by` :
QUI est dans `entity_field_audits` (champ `promesse_corbeille`,
payload `par` / `user_id`) ; QUAND = `deleted_at` + `created_at`
de l’audit.

Pivot `promesse_parcelle` **conservé** (consultation). Documents
intacts (pas de `Storage::delete`). Actes intacts.

## RECALCUL STATUT

Après `delete()`, `ParcelleStatutService::recalculerIds`.
`chargerFaits` : `pr.statut = signe` AND `pr.deleted_at IS NULL`
sur le pivot. Donc :

- autre promesse **signée** sur la même parcelle → reste Sous
  compromis (le statut vient du pivot, pas du dossier) ;
- `societe_detentrice_id` → Détenue (acte non touché) ;
- sinon : En négociation si offre, Opportunité si dossier vivant,
  Repérée sinon.

La confirmation simule `deduire()` sans CETTE promesse (les autres
signées restent dans les faits).

## CONSULTATION (#1589 déjà sur origin/main)

#1589 est dans `origin/main` (feature `df36dda1`). Statut déployé
OVH **non vérifié ici** : si la page Corbeille dossiers n’est pas
encore en prod, `git pull` + `migrate --force` du #1589 sont
préalables (même migration `deleted_at`).

Chemin minimal : étendre `Corbeille.vue` (section Promesses) +
`GET /foncier/dossiers/corbeille/promesses/{id}` lecture seule +
téléchargement documents (promesse et avenants) via la même route
download. Pas de restauration.

## AUTORISATION

`DossierFoncierCorbeilleDroits::userPeut()` = `m365GroupNames()`
brut, `GS_ADMIN_ERP`. `abort_unless` sur impact, destroy, show
corbeille, download. Jamais Gate. Le compte Robin prouve
l’autorisation, **nul** pour le refus.

## SYNTHÈSE

Soft delete d’une promesse non actée, confirmation des parcelles
Sous compromis, recalcul #1569 inchangé, journal + audit, lecture
admin sur la corbeille dossiers existante.

## DÉPLOIEMENT

```
git pull origin main
php artisan optimize:clear
php artisan view:clear
php artisan route:clear
php artisan journal:sync
```

Pas de migration #1593 (`deleted_at` déjà là).

## LEÇON

Le marqueur `(verrou)` n’est pas le statut Actée : après
déverrouillage direction, `verrouille` est faux mais `statut`
reste `acte`. Un refus corbeille qui ne regarderait que
`verrouille` laisserait supprimer l’engagement d’origine d’un
acte. `deleted_at` était déjà là pour la cascade dossier #1589 :
réutiliser, ne pas migrer. Qui sans `deleted_by` : audit append-only
sur le dossier (journal) et sur la promesse (liste corbeille).
Le test d’autorisation avec le compte Robin ne prouve pas le refus.
