---
suivi: 1803
date: 2026-10-07
sujet: Plafond, OCR situation, détail du marché
chantier: factures
type: correctif
statut: poussé
hash: be87c855
fichiers:
  - app/Models/Marche.php
  - app/Services/MontantFactureSousTraitantService.php
  - app/Http/Controllers/DepotFactureController.php
  - app/Services/DepotFactureClaudeAnalysisService.php
  - resources/js/Pages/DepotFactures/DepotFactureSaisieForm.vue
  - database/data/journal_mises_a_jour_post_2026_06_12.php
---

# SUIVI #1803 — plafond, OCR situation, détail du marché

## PROMPT ENVOYÉ

Correctif étroit du contrôle de plafond, de l’OCR des situations et du détail du marché. Suite de #1799 et de l’arrêt du #1800. Ne pas changer le sens de `depot_factures.montant_ht`. Aucun changement Sage.

## Fiches lues

- #1800 : arrêt. La colonne `montant_ht` est le dénominateur Sage du multi-fournisseur non étiqueté. Ce lot ne recalcule pas la colonne ; le plafond lit la somme des lignes postées.
- #1799 : le serveur prenait la colonne dès qu’elle était positive ; la fenêtre détail lisait le cache ; `recalculer` écrivait le payé dans `total_facture_ht`.
- #1801 : badge sans plafond et agrégat fiche (facturé, reste à facturer). Non modifié.
- #1778, #1796 : synchro CIE et libération RG inchangées. Le HT de travail de la libération reste appliqué après le montant posté.

## Étape 0 — lecteurs de `marches.total_facture_ht`

Écriture : `Marche::recalculer` mettait `paye_ht` dans la colonne.

Lecteurs de la colonne (pas des clés calculées homonymes) :

| Lecteur | Attendu |
|---|---|
| `DepotFactureController` payload saisie | facturé (repli d’affichage) |
| `MarcheController` déplacement et rapprochement, clé `facture_ht` | facturé |
| `BilanFinancierService` repli si la synthèse n’a pas de total | facturé |
| Tests rapprochement / déplacement | la colonne bouge avec les factures, nommée facturé |

La liste, la fiche et la synthèse lisent l’agrégat vivant, pas la colonne. Aucun lecteur n’attend le payé. `recalculer` écrit donc `facture_ht` (factures + reprise).

## Correctif

1. Plafond : somme des lignes Base HT postées, pas la colonne. L’envoi enregistre ces montants dans la même requête avant le contrôle. Message : déjà facturé, reprise SIWI, cette facture, cumul, plafond.
2. OCR : si cumul, situations précédentes et n° de situation, `montant_ht` est le montant de la situation. Clés facultatives `montant_cumule_ht`, `montant_precedent_ht`, `numero_situation`. Bandeau orange sur la saisie.
3. Détail du marché : facturé = agrégat hors facture courante + lignes en cours, reste et avancement sur le total du marché, mention de la reprise, badge sans plafond.
4. CIE : pas d’appel si `applicable_cie` est faux, rien n’est affiché. Échec réel : `Log::warning` avec le statut HTTP et le dépôt.

## DÉPLOIEMENT-TEST

1. Nouvelle situation : l’OCR propose le montant de la situation, bandeau avec le cumul.
2. Colonne ancienne, lignes modifiées, envoi sans enregistrer avant : le contrôle suit les lignes.
3. Vrai dépassement : message avec la reprise.
4. Détail MCH-2026-232 : facturé = reprise 73 876 + situation 3 716,80.
5. Marché sans CIE : plus de message « non chargées ».
6. Facture avec RG et CP : le plafond reste hors retenues, Sage inchangé.

`git pull origin main` puis, si le journal est parti : `php artisan view:clear` et `php artisan journal:sync`.

## LEÇON

Le plafond ne doit pas relire `depot_factures.montant_ht` quand la saisie poste les lignes. Cette colonne reste le dénominateur Sage du multi-fournisseur non étiqueté. `marches.total_facture_ht` est un cache de déjà facturé, pas de payé.
