---
name: project_2778sd
description: "Fonctionnalité déclaration mensuelle 2778-SD (PFO sur revenus étrangers) — matrice, simulation CERFA, report 2042, taux dynamiques, paramètre pfoAssujetti"
metadata: 
  node_type: memory
  type: project
  originSessionId: 984f7812-9585-45f1-be5b-5037de201a05
---

Onglet **2778-SD** dans la page Fiscalité (TaxReport), conditionné par la préférence `pfoAssujetti`.

**Architecture :**
- Backend : `GET /api/taxreport/2778` — matrice mensuelle par plateforme étrangère (domiciliation ≠ france), base = `interets_bruts_avant_local` si > 0 sinon `interets_bruts`
- Frontend : `Cerfa2778Preview.jsx` — deux sous-vues : Matrice mensuelle + Simulation CERFA
- TaxReport.jsx : onglet 2778-SD visible uniquement si `pfoAssujetti === true`

**Taux dynamiques :**
- Table `taux_pfu` enrichie : colonnes `csg`, `crds`, `solidarite` (migration dans index.js)
- Taux 2021-2025 : CSG 9,2 % | CRDS 0,5 % | Solidarité 7,5 % → PS total 17,2 % → PFU 30 %
- Taux 2026+ : CSG 10,6 % | CRDS 0,5 % | Solidarité 7,5 % → PS total 18,6 % → PFU 31,4 %
- `pfu.js` calcule `prelev_sociaux` et `pfu_total` automatiquement depuis les 3 composantes
- `getRatesForYear(annee, pfuList)` dans Cerfa2778Preview : trouve l'année exacte ou la plus proche

**Calcul cases CERFA (notre cas = placement revenu fixe) :**
- BA = intérêts bruts totaux (arrondi à l'euro)
- IA = BA × 12,8 % (PFO, acompte non libératoire)
- PQ = BA × CSG%, PV = BA × CRDS%, PF1 = PQ+PV, PG1 = BA × solidarité%
- PU = PF1, PK = PG1, QR = IA + PU + PK (montant à payer)

**Report annuel 2042 :**
- Case 2TR = total BA annuel (intérêts bruts)
- Case 2BH = idem 2TR (éviter double imposition PS)
- Case 2CK = total IA annuel (acompte déjà versé, imputable sur IR définitif)

**Paramètre pfoAssujetti :**
- Stocké dans `user_preferences` (clé `pfo_assujetti`) et `localStorage` (`cl_pfo_assujetti`)
- Exposé via `UiContext` : `pfoAssujetti`, `setPfoAssujetti`
- UI dans Settings > Flat Tax (PFU) : section "Fiscalité des plateformes étrangères", bloc accordéon avec toggle (masqué par défaut)
- Seuils : 25 000 € (célibataire) / 50 000 € (couple) de RFR de l'avant-dernière année

**Sélection plateformes persistée :** `localStorage` clé `cl_2778_excluded_plats` (array d'IDs exclus)

**Structure tableau CerfaBlock (Cerfa2778Preview.jsx) :**
- Grille 6 colonnes : `1fr 90px 90px 90px 90px 90px` → Libellé | Base imposable (BA) | Taux | Case | Montant | (sans titre, colonne Case SUP)
- Composant `Row` : props `label, code, value, highlight, note, caseSup, base, taux, noUnit` — `noUnit` supprime le symbole €, `whiteSpace: pre-line` sur le label pour les sauts de ligne
- Prop `mois` et `annee` passées à CerfaBlock depuis le parent pour afficher "Mai 2026" dans Montant
- Sections : Page de garde (page 1) | Prélèvement forfaitaire obligatoire non libératoire (page 2) | Prélèvements sociaux (page 3) | Totaux à reporter (page 4)
- Ligne BA+IA fusionnée : libellé sur 2 lignes (séparateur `\n`), code=IA, value=IA, taux=pfo%
- Ligne "Mois concerné" : code vide, value=`${MOIS_LABELS[mois]} ${annee}`, noUnit=true

**Settings > Flat Tax (PFU) :**
- Table : 7 colonnes (Année, PFU total, IR, PS total, └> dont CSG, └> dont CRDS, └> dont Solidarité)
- Fond indigo léger `rgba(99,102,241,0.06)` sur les 3 colonnes de décomposition
- Formulaires ajout/édition : saisir IR + CSG + CRDS + Solidarité → PFU total calculé automatiquement

**Why:** Obligation légale déclaration mensuelle PFO pour revenus d'intérêts de plateformes étrangères.
**How to apply:** Toujours vérifier `pfoAssujetti` avant d'afficher quoi que ce soit lié à la 2778-SD. Les taux viennent de `/api/pfu`, jamais hardcodés.
