# Rapport — v3.13.2 (facture PDF : derniers réglages avant déploiement)

**Lot du socle : se livre aux DEUX installations (IRADA et RUWAD), à l'identique.**
**Une migration additive (aucune donnée modifiée). Aucune commande de reprise.
Aucune dépendance composer nouvelle.**

---

## 1 — Deux options d'affichage de plus (par facture)

Dans la section « Options d'affichage » du formulaire, deux bascules **à OUI par défaut**
(défaut = comportement actuel → non-régression garantie sur les factures existantes et les
24 fixtures) :

- **« Afficher les sous-totaux de section »** (`show_section_subtotals`) : à non, les bandeaux
  de section restent mais les lignes « Sous-total HT — … » disparaissent du PDF. La bascule est
  **masquée** tant qu'aucune ligne de la facture ne porte de titre de section (sans objet).
- **« Afficher les numéros de lignes »** (`show_line_numbers`) : à non, la colonne **N°**
  disparaît du tableau ; ses 6 % de largeur reviennent à la désignation (45 → 51 % avec la
  colonne Unité, 57 → 63 % sans).

## 2 — N° de l'appel d'offres

- Champ optionnel **`tender_reference`** (« N° appel d'offres ») dans « Options d'affichage »,
  à côté du n° de BC / n° de décompte.
- **Pré-rempli** à la sélection d'un marché depuis son AO (`project->tender->reference`, repli
  sur la référence AO saisie sur le marché `ao_reference`) — même mécanique dans
  `createFromMilestone()` (génération depuis un décompte). Modifiable, effaçable.
- Rendu dans le bloc références du PDF : **« N° AO : … »**, seulement s'il est renseigné.

## 3 — Le pied de page descend au bas de la feuille

Le pied légal (ICE/RC/IF/TP + banque) s'affichait juste sous le contenu. Correctif par la
recette dompdf canonique :

- la marge basse de `@page` (**2,3 cm**) est la zone **réservée** au pied : le contenu ne peut
  jamais l'atteindre, donc jamais le chevaucher ;
- le pied `position: fixed; bottom: -2.0cm` est ancré **dans** cette marge (bottom négatif =
  sous le bord bas de la zone de contenu), à distance constante du bord de la feuille ;
- dompdf répète les éléments `fixed` sur **chaque page** d'une facture multi-pages.

**Vérifié au rendu réel** (PDF générés et inspectés page par page, pas seulement le CSS) :
pied au bas de la feuille sur une facture d'une page ET sur les deux pages d'une facture de
40 lignes, en-tête de tableau répété en page 2, aucun chevauchement.

## 4 — Une facture courante tient sur UNE page A4

Resserrement de densité seule — contenu, ordre des blocs et hiérarchie visuelle inchangés :

| Réglage | Avant | Après |
|---|---|---|
| Marges `@page` (haut / bas) | 1,5 / 3,2 cm | 1,2 / 2,3 cm |
| Padding lignes du tableau | 7 px | 4 px |
| Padding lignes des totaux | 6 px | 3 px |
| Marges verticales entre blocs | 14–16 px | 8–10 px |
| Hauteur du bloc signature | 80 px | 64 px (images max 44 px) |

Résultat, vérifié par rendu dompdf réel (nombre de pages du canvas, testé) : la facture type —
**8 lignes en 2 sections, RAS TVA 75 % + RAS IS 5 %, bloc règlement avec RIB, bloc signature,
réf. marché + N° AO + objet** — tient sur **une page**. Une facture de 40 lignes pagine
proprement (en-tête répété via `thead { display: table-header-group }`, pied fixe partout,
bandeaux de section protégés par `page-break-after: avoid`).

## Recette (tout au vert)

- Sous-totaux à non → plus aucune ligne « Sous-total », bandeaux intacts ; à oui (défaut) →
  inchangé. — `InvoicePdfViewTest`
- Numéros à non → colonne N° absente, largeur redistribuée ; à oui → inchangé. — `InvoicePdfViewTest`
- N° AO renseigné → visible ; vide → absent ; pré-remplissage depuis l'AO du marché (formulaire
  ET génération depuis décompte, avec repli `ao_reference`). — `InvoiceResourceTest`, `InvoiceServiceTest`
- Facture type (8 lignes, 2 sections, RIB, signature) → **1 page** ; facture de 40 lignes →
  multi-pages propre. Comptage de pages sur le rendu dompdf réel. — `InvoicePdfLayoutTest` (nouveau)
- Non-régression : les 24 fixtures ne portent aucun marquage nouveau (« N° AO » ajouté à la
  liste), colonne N° toujours là par défaut, totaux/PDF/numérotation v3.13.0–v3.13.1 intacts —
  suite complète verte + `pint` + `npm run build`.

## Fichiers touchés

- `database/migrations/2026_08_22_130000_add_pdf_preferences_to_invoices.php` — additive :
  `tender_reference` (nullable), `show_section_subtotals` / `show_line_numbers` (booléens, défaut vrai)
- `app/Models/Invoice.php` — fillable + casts
- `app/Services/Invoices/InvoiceService.php` — pré-remplissage `tender_reference` depuis le décompte
- `app/Filament/Admin/Resources/Invoices/Schemas/InvoiceForm.php` — champ N° AO, deux bascules,
  pré-remplissage à la sélection du marché
- `resources/views/pdf/invoice.blade.php` — options, « N° AO », pied ancré dans la marge, densité
- `tests/Feature/Invoices/InvoicePdfLayoutTest.php` (nouveau) + vues/service/ressource/non-régression
