---
suivi: 1599
date: 2026-09-17
sujet: Abandon destination facture Projet
chantier: factures / depot
type: feature
statut: poussé
hash: a231728c
fichiers:
  - app/Http/Controllers/DepotFactureController.php
  - app/Support/DepotFactureProjetAncrage.php
  - app/Http/Controllers/FactureGlobaleController.php
  - app/Services/FactureGlobaleListeQuery.php
  - resources/js/Pages/DepotFactures/DepotFactureSaisieForm.vue
  - resources/js/Pages/Factures/Global.vue
  - tests/Unit/DepotFacture1599AbandonDestinationProjetSourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
  - docs/suivi/SUIVI_1599_abandon_facture_projet.md
---

# SUIVI #1599 — Abandon facture destination Projet

## PROMPT ENVOYÉ

Retirer la destination PROJET de la saisie et l’onglet Projet de la
liste. Conserver `depot_factures.dossier_foncier_id` et le JSON
historique. Pas de migration. Pas de retouche Foncier / compta / Sage.

## FICHES LUES

- **#1591 LEÇON** — colonne conservée, plus écrite ni proposée
  (prix demandé). Impact : même traitement pour `dossier_foncier_id`.
- **#1507 LEÇON** — onglet = colonne FK, pas le JSON. Impact : onglet
  retiré ; URL `tab=projet` repliée sur Tous, pas d’erreur.
- **#1515 / #1559 LEÇON** — Enregistrer permissif ; CLASSID à la
  comptabilisation. Impact : ComptabilisationController non touché.
- **#1492 / #1513 LEÇON** — `required_if` / `prohibited_unless` /
  `assertDestinationProjetCoherence`. Impact : règles et méthode
  supprimées ; ancrage n’écrit plus la FK.
- **#1598 LEÇON** — lint ≠ variable d’une branche supprimée. Impact :
  `$ocrSaisieAvant` posé avant usage ; plus de `$dossierId` d’assert.

## MAPPING (saisie)

| Libellé affiché | Valeur postée | Colonne / JSON | Back |
|---|---|---|---|
| PROGRAMMES | `PROGRAMMES` | `ocr_raw.saisie.destination` | Programmes |
| FRAIS GÉNÉRAUX | `FRAIS_GENERAUX` | idem | Frais généraux |
| (plus proposé) | `PROJET` | conservé en lecture | Projet (historique) |

`PROJETS` (pluriel) : toujours refusé à l’écriture.

## DÉPÔTS HISTORIQUES

Repli : destination hors référentiel d’écriture → pas de fatal.
Saisie : bandeau « Ancienne destination Projet » ; sélecteur à deux
valeurs ; fiche lisible. Enregistrer brouillon encore possible si le
JSON porte déjà `PROJET`. Envoi en validation : refusé (« rattachez
à un programme »). Aucune réécriture de masse du JSON. Robin traite.

URL liste `?tab=projet` → onglet Tous (`normalizeTab`).

## REQUÊTE SQL (dépôts vivants destination PROJET)

SELECT
    df.id,
    df.uuid,
    df.statut,
    df.montant_ht,
    df.montant_ttc,
    df.dossier_foncier_id,
    df.programme_id,
    JSON_UNQUOTE(JSON_EXTRACT(df.ocr_raw, '$.saisie.destination')) AS dest_saisie,
    JSON_UNQUOTE(JSON_EXTRACT(df.ocr_raw, '$.destination')) AS dest_ocr
FROM depot_factures df
WHERE df.deleted_at IS NULL
  AND (
        JSON_UNQUOTE(JSON_EXTRACT(df.ocr_raw, '$.saisie.destination')) = 'PROJET'
     OR JSON_UNQUOTE(JSON_EXTRACT(df.ocr_raw, '$.destination')) = 'PROJET'
  )
ORDER BY df.id;

Non exécutée ici (MySQL local non joignable). À lancer en prod.

## RECENSEMENT DES POINTS D’USAGE

| Point | Fichier | Traitement |
|---|---|---|
| Sélecteur destination | `DepotFactureSaisieForm.vue` | PROJET retiré ; bandeau lecture historique |
| Champ dossier | idem + `DepotProjetDossierFields.vue` | champ retiré ; composant conservé, plus monté |
| Règles draft / valider | `DepotFactureController` | plus de `dossier_foncier_id` ; PROJET hors écriture (brouillon historique toléré) |
| `assertDestinationProjetCoherence` | idem | **supprimé** |
| Ancrage FK / JSON | `DepotFactureProjetAncrage` | n’écrit plus `dossier_foncier_id` |
| `applyDepotSaisieFromValidated` | contrôleur | ne pose plus la FK ; recopie la clé JSON existante |
| `appendDirectFkColumnsToUpdates` | contrôleur | plus d’écriture `dossier_foncier_id` |
| Masse / Outlook | `masseDestinationValidationRules` | PROGRAMMES / FG seulement |
| OCR Claude | `DepotFactureClaudeAnalysisService` | déjà sans PROJET — inchangé |
| Recherche dossiers | `searchDossiersProjet` + routes | endpoints conservés, plus d’UI |
| Onglet liste | `FactureGlobaleListeQuery` + `Global.vue` | onglet et compteur retirés |
| URL `tab=projet` | `FactureGlobaleController::normalizeTab` | repli Tous |
| Colonne / payload `projet` | sérialisation liste | conservés (non affichés) |
| Fiche facture dossier | `Factures/Show.vue` + `FactureController` | **lecture** conservée si FK présente |
| Paiement fonds propres | `PaiementFondsPropres` + `Paiement/Index.vue` | PROJET laissé (éligibilité historique) — pas Sage |
| Comptabilisation / CLASSID | `ComptabilisationController` | **non touché** ; CLASSID = programme (`intacctClassAnalytics`) ; aucun `dossier_foncier` |
| Envoi Sage | idem | inchangé |
| Workflow NV1/NV2 | `valider` / `EngagerWorkflowService` | appels ancrage conservés ; FK plus écrite |
| Bilan / budget | `BilanFinancierService` | aucun usage destination PROJET / FK dépôt |
| Tableau de bord compta | `ComptaTableauBordService` | non touché |
| Filtres boîte dépôt | `destination.*` | lecture inclut encore `PROJET` |
| Module Foncier | dossiers, parcelles, postes | **non touché** |

## DÉPLOIEMENT

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

Pas de migrate. `route:clear` inutile (aucune route ajoutée/supprimée).

## LEÇON

Abandonner une destination : la retirer de l’écriture et de l’UI, pas
de la colonne ni du JSON. Un `tab` d’URL hors UI se replie, il ne
422. L’ancrage qui nullifiait `dossier_foncier_id` hors PROJET **était
une écriture** : l’arrêter, sinon on efface l’historique au premier
Enregistrer PROGRAMMES.
