# Rapport — v3.14.0 (cadre du cachet à taille réelle + le devis rejoint la facture)

**Lot du socle, deux commits (A : cachet · B : devis) : se livre aux DEUX installations, à
l'identique. Une migration additive et idempotente (`Schema::hasColumn`). Aucune dépendance,
pas de montée de vendor.**

## A — Le cadre du cachet à taille de tampon physique

Constaté sur le scan de la facture réelle 16-2026 : le tampon encreur débordait largement sous
un cadre de 58–80 px (1,5–2,1 cm) quand un tampon d'entreprise fait 3,5–4 cm.

- **Hauteur intérieure utile ≥ 3,8 cm (144 px)** sous le libellé, cadre à **165 px**,
  **identique en confort ET en compact** : un espace de tamponnage ne se comprime pas avec la
  densité. Largeur inchangée (~49 %).
- Images embarquées (option « avec cachet ») à **~90 % de la hauteur intérieure** (130 px max),
  strictement contenues, ratio conservé (`max-height` + `max-width` combinés, jamais forcés).
- **La densité adaptative absorbe le surcoût** : le compact des deux gabarits a été resserré
  d'un cran sur les zones non critiques (logo 44 px, interlignes 1,4, paddings de lignes 2 px,
  totaux 2 px, marges de blocs 4–6 px) — jamais sur le cadre. Les trois profils de recette
  facture gardent leur pagination (3 lignes → confort 1 page · 16-2026 → compact 1 page ·
  40 lignes → confort ≥ 2 pages), y compris avec un N° d'AO en plus (le déclencheur du
  resserrement : constaté au rendu réel, le profil + N° AO basculait).

## B — Le devis rejoint la facture

`pdf.quote` refondu sur le modèle exact du gabarit facture v3.13.6 :

- **En-tête** « DEVIS N° X » sur une ligne (gras, 18 px) ; dessous Date + Validité.
- **Bloc références** : Réf. marché / N° AO / Objet / Validité — colonnes miroir ajoutées sur
  `quotes` (`market_reference`, `tender_reference`) + **`project_id`** : le devis se rattache
  désormais à un marché, avec le même pré-remplissage que la facture (références, n° d'AO
  depuis `project->tender` avec repli `ao_reference`, objet, client via le contact du marché,
  RAS IS si marché public) — champs modifiables.
- **Sections** : bandeaux + sous-totaux **masquables** et **numéros de lignes masquables** —
  mêmes colonnes de préférences que `invoices` (`show_section_subtotals`,
  `show_line_numbers`, défaut OUI = rendu actuel), mêmes bascules au formulaire.
- **Mise en page** : marges 1,0 cm, désignation ≥ 58 % (62 % sans numéros), montants à 13 %
  jamais tronqués, arrêté en lettres, coordonnées bancaires, **deux cadres §A** (prestataire /
  bon pour accord client), **pied légal 2 lignes ancré dans la marge basse** (recette dompdf
  `bottom` négatif), répété au bas de chaque page.
- **Densité adaptative** : `DensitePdf` branché sur `QuoteDocumentController` ET la pièce
  jointe de l'e-mail au client (`QuoteSentToClient`) — règle d'or v3.13.6 respectée (rendus
  de comptage jetables, instance retournée jamais rendue). Le Courrier ne génère pas de PDF
  devis (factures seulement) : rien d'autre à brancher.
- **Téléchargement avec/sans cachet + « PDF personnalisé »** : déjà en place sur la ressource
  Devis (mêmes boutons que la facture) — inchangés.
- **Conversion devis → facture** : marché, références et préférences d'affichage **suivent**
  (les sections suivaient depuis v3.13.0) ; traçabilité `quote_id` intacte.

## Recette (tout au vert, rendu dompdf réel)

- Cadre cachet ≥ 3,8 cm dans le HTML des DEUX gabarits et des DEUX densités ; images
  contenues. — `InvoicePdfViewTest`, `QuotePdfLayoutTest`
- Non-régression facture : les 3 profils v3.13.5 gardent leur pagination. — `InvoicePdfLayoutTest`
- `QuotePdfLayoutTest` (nouveau) : devis 3 lignes → confort 1 page · devis 10 lignes,
  2 sections + sous-totaux, RAS → 1 page · devis 40 lignes → confort ≥ 2 pages (en-tête de
  tableau répété, pied partout, bandeaux protégés).
- Options du devis (sous-totaux, numéros) vérifiées ; pré-remplissage marché au formulaire ;
  conversion conserve sections + références + options. — `QuoteResourceTest`, `QuoteServiceTest`
- Suite complète verte + `pint` + `npm run build`. PDF témoins inspectés page à page.

## Fichiers touchés

- `resources/views/pdf/invoice.blade.php` — cadre §A, compact resserré
- `resources/views/pdf/quote.blade.php` — refonte complète sur le modèle facture
- `database/migrations/2026_08_22_150000_add_market_context_and_pdf_preferences_to_quotes.php`
- `app/Models/Quote.php` — fillable/casts + relation `project()`
- `app/Filament/Admin/Resources/Quotes/Schemas/QuoteForm.php` — marché lié, références, bascules
- `app/Services/Quotes/QuoteService.php` — la conversion emporte marché/références/préférences
- `app/Http/Controllers/QuoteDocumentController.php`, `app/Mail/QuoteSentToClient.php` — densité
- Tests : `QuotePdfLayoutTest` (nouveau), `QuoteResourceTest`, `QuoteServiceTest`,
  `InvoicePdfViewTest`
