Amélioration de la fonctionnalité Fiscalité
This commit is contained in:
1 parent
5437091884
commit
5dc6f21e61
7 files changed
+1206
-189
No files matched your search
@@ -343,6 +343,172 @@ export default function Aide() {
|
||||
</p>
|
||||
</FaqItem>
|
||||
|
||||
<FaqSectionTitle>Fiscalité</FaqSectionTitle>
|
||||
|
||||
<FaqItem question="Comment la fiscalité fonctionne-t-elle dans Crowdlending ?" openQuestion={openQuestion} setOpenQuestion={setOpenQuestion}>
|
||||
<p style={{ marginTop: 0 }}>
|
||||
La page <strong style={{ color: 'var(--text)' }}>Fiscalité</strong> (menu de gauche) reprend, année par année,
|
||||
les montants nécessaires pour préparer votre déclaration de revenus. Elle est organisée en quatre onglets,
|
||||
chacun correspondant à un formulaire CERFA officiel :
|
||||
</p>
|
||||
|
||||
<table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 'var(--fs-sm)', margin: '0 0 14px' }}>
|
||||
<tbody>
|
||||
<tr style={{ borderBottom: '1px solid var(--border)' }}>
|
||||
<td style={{ padding: '8px 10px 8px 0', verticalAlign: 'top', whiteSpace: 'nowrap' }}>
|
||||
<code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2561</code>
|
||||
</td>
|
||||
<td style={{ padding: '8px 0', verticalAlign: 'top' }}><strong style={{ color: 'var(--text)' }}>IFU — Imprimé fiscal unique.</strong> Récapitulatif annuel transmis par les plateformes françaises soumises au prélèvement forfaitaire unique (PFU).</td>
|
||||
</tr>
|
||||
<tr style={{ borderBottom: '1px solid var(--border)' }}>
|
||||
<td style={{ padding: '8px 10px 8px 0', verticalAlign: 'top', whiteSpace: 'nowrap' }}>
|
||||
<code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2047</code>
|
||||
</td>
|
||||
<td style={{ padding: '8px 0', verticalAlign: 'top' }}><strong style={{ color: 'var(--text)' }}>Revenus encaissés à l'étranger.</strong> Visible dès qu'une ou plusieurs de vos plateformes sont domiciliées hors de France ; détaille les intérêts perçus pays par pays et le crédit d'impôt associé.</td>
|
||||
</tr>
|
||||
<tr style={{ borderBottom: '1px solid var(--border)' }}>
|
||||
<td style={{ padding: '8px 10px 8px 0', verticalAlign: 'top', whiteSpace: 'nowrap' }}>
|
||||
<code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2778-SD</code>
|
||||
</td>
|
||||
<td style={{ padding: '8px 0', verticalAlign: 'top' }}><strong style={{ color: 'var(--text)' }}>Prélèvement forfaitaire obligatoire (PFO)</strong>, selon votre situation fiscale — déclaration mensuelle de l'acompte dû sur les intérêts de plateformes étrangères (voir la question suivante).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{ padding: '8px 10px 8px 0', verticalAlign: 'top', whiteSpace: 'nowrap' }}>
|
||||
<code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2042</code>
|
||||
</td>
|
||||
<td style={{ padding: '8px 0', verticalAlign: 'top' }}><strong style={{ color: 'var(--text)' }}>Déclaration des revenus.</strong> La déclaration principale : reprend les cases calculées à partir des trois formulaires ci-dessus (2TT, 2TR, 2BH, 2CK, 2TY).</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>Le sens de circulation des données est toujours le même :</p>
|
||||
<ul style={{ margin: '8px 0 12px 16px', paddingLeft: 0, lineHeight: 1.8 }}>
|
||||
<li><code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2561</code> et <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2047</code> alimentent directement la <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2042</code>.</li>
|
||||
<li>La <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2778-SD</code> (mensuelle) alimente la <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2047</code> (annuelle), qui seule est ensuite reportée sur la 2042 — la 2778-SD n'est qu'un mécanisme d'acompte intermédiaire, jamais une déclaration de substitution à la 2047.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Un pavé « À quoi correspond chaque CERFA ? », avec un schéma récapitulatif, est affiché directement en haut de
|
||||
l'onglet 2047 lorsque vous avez des plateformes étrangères.
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: 0 }}>
|
||||
<strong style={{ color: 'var(--text)' }}>Important</strong> — ce module est une aide à la préparation de votre
|
||||
déclaration, il ne la remplace pas. Vérifiez chaque montant avant de le reporter sur le site des impôts :
|
||||
vous restez seul responsable de l'exactitude de votre déclaration fiscale, Crowdlending ne saurait être
|
||||
tenu responsable des données déclarées.
|
||||
</p>
|
||||
</FaqItem>
|
||||
|
||||
<FaqItem question="Comment savoir si je suis concerné par la déclaration mensuelle sur mes plateformes étrangères ?" openQuestion={openQuestion} setOpenQuestion={setOpenQuestion}>
|
||||
<p style={{ marginTop: 0 }}>
|
||||
Cette question concerne le formulaire <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2778-SD</code> (prélèvement
|
||||
forfaitaire obligatoire, ou PFO). Elle ne se pose que si vous détenez au moins une plateforme domiciliée
|
||||
hors de France.
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '16px 0 8px', color: 'var(--text)' }}>La règle</h4>
|
||||
<p>
|
||||
Le PFO s'applique aux personnes physiques fiscalement domiciliées en France dont le <strong style={{ color: 'var(--text)' }}>revenu
|
||||
fiscal de référence (RFR)</strong> de l'avant-dernière année est égal ou supérieur à :
|
||||
</p>
|
||||
<div style={{ display: 'flex', gap: 12, margin: '8px 0 12px', flexWrap: 'wrap' }}>
|
||||
<div style={{ padding: '6px 14px', borderRadius: 20, background: 'rgba(99,102,241,0.08)', border: '1px solid rgba(99,102,241,0.2)', fontSize: 'var(--fs-sm)', fontWeight: 600 }}>
|
||||
25 000 € — célibataire, divorcé ou veuf
|
||||
</div>
|
||||
<div style={{ padding: '6px 14px', borderRadius: 20, background: 'rgba(99,102,241,0.08)', border: '1px solid rgba(99,102,241,0.2)', fontSize: 'var(--fs-sm)', fontWeight: 600 }}>
|
||||
50 000 € — couple marié ou pacsé
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
Votre RFR figure sur votre <strong style={{ color: 'var(--text)' }}>avis d'imposition</strong> de l'année précédente
|
||||
(ligne « Revenu fiscal de référence »). En dessous de ces seuils, vous êtes dispensé du PFO — mais les
|
||||
prélèvements sociaux restent dus.
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '16px 0 8px', color: 'var(--text)' }}>Où l'activer dans l'application</h4>
|
||||
<ol style={{ margin: '0 0 12px 16px', paddingLeft: 0, lineHeight: 1.8 }}>
|
||||
<li>Allez dans <strong style={{ color: 'var(--text)' }}>Paramétrage → Ma fiscalité</strong>.</li>
|
||||
<li>Dépliez la carte <strong style={{ color: 'var(--text)' }}>« CERFA 2778-SD — Prélèvement Forfaitaire Obligatoire (PFO) pour des revenus de source étrangère »</strong> pour revoir le détail des seuils.</li>
|
||||
<li>Activez le bouton si votre situation vous rend redevable du PFO.</li>
|
||||
</ol>
|
||||
<p>
|
||||
Ce réglage est global : une fois activé, l'onglet <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2778-SD</code> apparaît
|
||||
dans la page Fiscalité, les cases <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2BH</code> / <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2CK</code> se
|
||||
remplissent dans le report 2042, et les lignes de suivi mensuel du PFO (taux, montant à payer, intérêt net)
|
||||
s'affichent dans les tableaux « Suivi mensuel » des onglets 2047 et 2778-SD. Si vous le désactivez, ces
|
||||
éléments sont masqués car ils ne s'appliquent pas à votre situation.
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: 0 }}>
|
||||
<strong style={{ color: 'var(--text)' }}>À retenir</strong> — que le PFO s'applique ou non à vous, la déclaration
|
||||
annuelle via le CERFA 2047 reste <strong style={{ color: 'var(--text)' }}>obligatoire</strong> dès que vous avez
|
||||
perçu des intérêts d'une plateforme étrangère. Ce paramètre reflète votre propre situation fiscale : en cas
|
||||
de doute, vérifiez votre avis d'imposition ou consultez un professionnel.
|
||||
</p>
|
||||
</FaqItem>
|
||||
|
||||
<FaqItem question="Comment est calculé le crédit d'impôt sur les intérêts perçus d'une plateforme étrangère ?" openQuestion={openQuestion} setOpenQuestion={setOpenQuestion}>
|
||||
<p style={{ marginTop: 0 }}>
|
||||
Dans l'onglet <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2047</code>, vue
|
||||
« Données 2047 », chaque plateforme étrangère est classée automatiquement selon la convention fiscale
|
||||
signée entre la France et son pays de domiciliation.
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '16px 0 8px', color: 'var(--text)' }}>Éligible au crédit d'impôt (cases 233 à 238)</h4>
|
||||
<p>
|
||||
Le pays a une convention fiscale <strong style={{ color: 'var(--text)' }}>active</strong> et n'impose pas
|
||||
l'imposition exclusivement dans le pays de résidence. Le crédit d'impôt (case 237) est égal à l'impôt
|
||||
réellement prélevé à l'étranger (case 236), plafonné au taux conventionnel du pays lorsque celui-ci est
|
||||
chiffré (case 234) — ou <strong style={{ color: 'var(--text)' }}>non plafonné</strong> pour certains pays dont
|
||||
la convention prévoit un crédit égal à l'impôt prélevé sans limite de taux.
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '16px 0 8px', color: 'var(--text)' }}>Non éligible (case 250)</h4>
|
||||
<p>
|
||||
Le pays est absent des conventions fiscales référencées, sa convention est suspendue ou caduque, ou elle
|
||||
prévoit une imposition exclusivement dans le pays de résidence. Dans ce cas, aucun crédit d'impôt n'est
|
||||
calculé.
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '16px 0 8px', color: 'var(--text)' }}>Sous-totaux par pays</h4>
|
||||
<p style={{ marginBottom: 0 }}>
|
||||
Le formulaire papier 2047 se remplit <strong style={{ color: 'var(--text)' }}>par pays</strong>, pas par
|
||||
plateforme : si plusieurs de vos plateformes sont domiciliées dans le même pays, une ligne « Sous-total »
|
||||
apparaît automatiquement sous le groupe pour faciliter le report. Les totaux 8VL et 8PL (report 2042)
|
||||
ainsi que les cases 251/252 cumulent l'ensemble de vos plateformes étrangères, arrondis à l'euro comme
|
||||
l'exige le formulaire officiel.
|
||||
</p>
|
||||
</FaqItem>
|
||||
|
||||
<FaqItem question="Comment utiliser les onglets de la page Fiscalité pour remplir ma déclaration ?" openQuestion={openQuestion} setOpenQuestion={setOpenQuestion}>
|
||||
<p style={{ marginTop: 0 }}>
|
||||
Chaque onglet CERFA propose généralement plusieurs vues : un <strong style={{ color: 'var(--text)' }}>suivi
|
||||
mensuel</strong> (le détail plateforme par plateforme, mois par mois), une vue <strong style={{ color: 'var(--text)' }}>« Données »</strong> (les
|
||||
cases du formulaire lui-même), et une vue <strong style={{ color: 'var(--text)' }}>« Report 2042 »</strong> (ce
|
||||
qui doit être reporté sur la déclaration principale).
|
||||
</p>
|
||||
|
||||
<h4 style={{ margin: '16px 0 8px', color: 'var(--text)' }}>Ordre suggéré</h4>
|
||||
<ol style={{ margin: '0 0 12px 16px', paddingLeft: 0, lineHeight: 1.8 }}>
|
||||
<li>Sélectionnez l'<strong style={{ color: 'var(--text)' }}>année</strong> concernée en haut de la page.</li>
|
||||
<li>Onglet <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2561</code> si vous avez des plateformes françaises soumises au PFU.</li>
|
||||
<li>Onglets <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2778-SD</code> puis <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2047</code> si vous avez des plateformes étrangères — le suivi mensuel du 2778-SD documente le détail, la vue « Données 2047 » regroupe l'annuel par pays.</li>
|
||||
<li>Onglet <code style={{ background: 'var(--surface-2)', padding: '1px 5px', borderRadius: 4 }}>2042</code> en dernier : sa vue « Données 2042 » et sa synthèse fiscale récapitulent toutes les cases (2TT, 2TR, 2BH, 2CK, 2TY) à saisir sur le site des impôts.</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Les montants affichés dans les vues « Données » et les cases officielles sont arrondis à l'euro, comme
|
||||
l'exigent les formulaires CERFA (les montants intermédiaires du suivi mensuel restent au centime près,
|
||||
pour la traçabilité).
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: 0 }}>
|
||||
Comme rappelé sur la page elle-même : ce module est une <strong style={{ color: 'var(--text)' }}>aide à la
|
||||
préparation</strong> de votre déclaration, il ne s'y substitue pas. Contrôlez chaque case avant de la
|
||||
reporter — vous restez seul responsable de l'exactitude de votre déclaration.
|
||||
</p>
|
||||
</FaqItem>
|
||||
|
||||
<FaqSectionTitle>API et Serveur MCP pour l'IA</FaqSectionTitle>
|
||||
|
||||
<FaqItem question="Comment configurer le serveur MCP pour l'utiliser dans Claude Desktop" openQuestion={openQuestion} setOpenQuestion={setOpenQuestion}>
|
||||
|
||||
@@ -313,7 +313,7 @@ export default function Plateformes() {
|
||||
setSearchParams(p => { const n = new URLSearchParams(p); n.set('plat', nom); return n; }, { replace: true });
|
||||
};
|
||||
const [selectedDetenteurId, setSelectedDetenteurId] = useState(() => { try { return localStorage.getItem('cl_plat_detenteur') || 'all'; } catch { return 'all'; } });
|
||||
const [selectedYear, setSelectedYear] = useState(() => { try { return localStorage.getItem('cl_plat_year') || String(new Date().getFullYear()); } catch { return String(new Date().getFullYear()); } });
|
||||
const [selectedYear, setSelectedYear] = useState(''); // toujours "Depuis le début" au démarrage de la page
|
||||
const [windowStart, setWindowStart] = useState(0);
|
||||
const [drDetaille, setDrDetaille] = useState(() => {
|
||||
try { return localStorage.getItem('cl_dr_plat_detaille') === 'true'; } catch { return false; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import PageIcon from '../components/PageIcon.jsx';
|
||||
import EmptyState from '../components/EmptyState.jsx';
|
||||
import Pagination from '../components/Pagination.jsx';
|
||||
@@ -10,6 +11,7 @@ import { fmtEUR, fmtStatut } from '../utils/format.js';
|
||||
import Cerfa2561Preview from '../components/Cerfa2561Preview.jsx';
|
||||
import CerfaRecapTable from '../components/CerfaRecapTable.jsx';
|
||||
import Cerfa2778Preview from '../components/Cerfa2778Preview.jsx';
|
||||
import Cerfa2047Preview from '../components/Cerfa2047Preview.jsx';
|
||||
import Cerfa2042Preview from '../components/Cerfa2042Preview.jsx';
|
||||
|
||||
/* ── YearSelector ────────────────────────────────────────────── */
|
||||
@@ -144,8 +146,78 @@ function ExportDropdown({ disabled, onCSV, onJSON }) {
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Ligne d'explication d'un formulaire CERFA ── */
|
||||
function InfoLigneCerfa({ code, titre, texte }) {
|
||||
return (
|
||||
<div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
|
||||
<div style={{
|
||||
flexShrink: 0, minWidth: 62, textAlign: 'center',
|
||||
fontFamily: 'monospace', fontWeight: 800, fontSize: 'var(--fs-xs)',
|
||||
color: 'var(--primary)', background: 'rgba(99,102,241,0.07)',
|
||||
borderRadius: 6, padding: '4px 6px', letterSpacing: '.03em', whiteSpace: 'nowrap',
|
||||
}}>{code}</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 'var(--fs-sm)', fontWeight: 600 }}>{titre}</div>
|
||||
<div style={{ fontSize: 'var(--fs-xs)', color: 'var(--text-muted)', marginTop: 2, lineHeight: 1.5 }}>{texte}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Schéma : quel formulaire alimente quel formulaire ── */
|
||||
function CerfaFlowDiagram({ hasEtranger }) {
|
||||
const boxFill = 'var(--surface-2)';
|
||||
const box = (x, y, w, h, code, label, highlight) => (
|
||||
<g key={code}>
|
||||
<rect x={x} y={y} width={w} height={h} rx={10}
|
||||
fill={highlight ? 'rgba(99,102,241,0.08)' : boxFill}
|
||||
stroke={highlight ? 'var(--primary)' : 'var(--border)'} strokeWidth={highlight ? 1.8 : 1.3} />
|
||||
<text x={x + w / 2} y={y + h / 2 - 6} textAnchor="middle" fontFamily="monospace" fontWeight="800"
|
||||
fontSize="14" fill="var(--primary)">{code}</text>
|
||||
<text x={x + w / 2} y={y + h / 2 + 13} textAnchor="middle" fontSize="10" fill="var(--text-muted)">{label}</text>
|
||||
</g>
|
||||
);
|
||||
const arrow = (x1, y1, x2, y2, key) => (
|
||||
<line key={key} x1={x1} y1={y1} x2={x2} y2={y2}
|
||||
stroke="var(--text-muted)" strokeWidth={1.6} markerEnd="url(#cerfaFlowArrow)" />
|
||||
);
|
||||
const markerDef = (
|
||||
<defs>
|
||||
<marker id="cerfaFlowArrow" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto">
|
||||
<path d="M0,0 L6,3 L0,6 Z" fill="var(--text-muted)" />
|
||||
</marker>
|
||||
</defs>
|
||||
);
|
||||
|
||||
if (!hasEtranger) {
|
||||
return (
|
||||
<svg viewBox="0 0 420 80" style={{ width: '100%', maxWidth: 420, height: 'auto', display: 'block' }}>
|
||||
{markerDef}
|
||||
{arrow(160, 40, 228, 40, 'a1')}
|
||||
{box(20, 15, 140, 50, '2561', 'IFU')}
|
||||
{box(230, 15, 170, 50, '2042', 'Déclaration revenus', true)}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<svg viewBox="0 0 620 250" style={{ width: '100%', maxWidth: 560, height: 'auto', display: 'block' }}>
|
||||
{markerDef}
|
||||
{arrow(520, 58, 520, 98, 'a1')}
|
||||
{arrow(100, 148, 260, 190, 'a2')}
|
||||
{arrow(520, 148, 362, 190, 'a3')}
|
||||
|
||||
{box(440, 8, 160, 50, '2778-SD', 'PFO mensuel')}
|
||||
{box(20, 98, 160, 50, '2561', 'IFU')}
|
||||
{box(440, 98, 160, 50, '2047', 'Revenus étranger')}
|
||||
{box(210, 190, 200, 54, '2042', 'Déclaration revenus', true)}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
/* ── Composant principal ─────────────────────────────────────── */
|
||||
export default function TaxReport() {
|
||||
const navigate = useNavigate();
|
||||
const { activeId, activeView } = useInvestisseur();
|
||||
const { pfoAssujetti } = useUi();
|
||||
const [annee, setAnnee] = useState(String(new Date().getFullYear()));
|
||||
@@ -157,10 +229,14 @@ export default function TaxReport() {
|
||||
const [detailExpanded, setDetailExpanded] = useState(false);
|
||||
const [cerfaExpanded, setCerfaExpanded] = useState(false);
|
||||
const [hasPlateformes, setHasPlateformes] = useState(true); // true par défaut pour éviter un flash du mauvais message
|
||||
const [hasEtranger, setHasEtranger] = useState(false); // au moins une plateforme étrangère configurée (pour l'onglet CERFA 2047 — indépendant de l'année sélectionnée, même principe que le 2778-SD)
|
||||
|
||||
/* ── Plateformes configurées ? (pour distinguer "pas de plateforme" de "pas encore de données") ── */
|
||||
useEffect(() => {
|
||||
api.get('/plateformes').then(p => setHasPlateformes((p || []).length > 0)).catch(() => {});
|
||||
api.get('/plateformes').then(p => {
|
||||
setHasPlateformes((p || []).length > 0);
|
||||
setHasEtranger((p || []).some(pl => pl.domiciliation && pl.domiciliation !== 'FR'));
|
||||
}).catch(() => {});
|
||||
}, []);
|
||||
|
||||
/* ── Chargement des années disponibles ── */
|
||||
@@ -196,14 +272,14 @@ export default function TaxReport() {
|
||||
setData2042({
|
||||
case_2TT: frLignes.reduce((s, l) => s + (l.case_2TT ?? 0), 0),
|
||||
case_2TR: frLignes.reduce((s, l) => s + (l.case_2TR ?? 0), 0) + Math.round(platEtr.reduce((s, p) => s + etrBA(p), 0)),
|
||||
case_2BH: frLignes.reduce((s, l) => s + (l.case_2BH ?? 0), 0) + Math.round(platEtr.reduce((s, p) => s + etrBA(p), 0)),
|
||||
case_2CK: frLignes.reduce((s, l) => s + (l.case_2CK ?? 0), 0) + Math.round(platEtr.reduce((s, p) => s + etrBA(p), 0) * pfo),
|
||||
case_2BH: frLignes.reduce((s, l) => s + (l.case_2BH ?? 0), 0) + (pfoAssujetti ? Math.round(platEtr.reduce((s, p) => s + etrBA(p), 0)) : 0),
|
||||
case_2CK: frLignes.reduce((s, l) => s + (l.case_2CK ?? 0), 0) + (pfoAssujetti ? Math.round(platEtr.reduce((s, p) => s + etrBA(p), 0) * pfo) : 0),
|
||||
case_2TY: frLignes.reduce((s, l) => s + (l.case_2TY ?? 0), 0),
|
||||
});
|
||||
}).finally(() => setLoading(false));
|
||||
};
|
||||
|
||||
useEffect(load, [activeId, activeView, annee]); // eslint-disable-line
|
||||
useEffect(load, [activeId, activeView, annee, pfoAssujetti]); // eslint-disable-line
|
||||
|
||||
/* ── Pagination détail ── */
|
||||
const detail = data?.detail ?? [];
|
||||
@@ -301,10 +377,73 @@ export default function TaxReport() {
|
||||
</p>
|
||||
</div>}
|
||||
|
||||
{!detailExpanded && !cerfaExpanded && data2042 && (
|
||||
<div className="card" style={{ marginTop: 16 }}>
|
||||
<h3 style={{ marginTop: 0, marginBottom: 10 }}>À quoi correspond chaque CERFA ?</h3>
|
||||
<div style={{ display: 'flex', gap: 28, alignItems: 'center', flexWrap: 'wrap' }}>
|
||||
<div style={{ flex: '1 1 320px', minWidth: 280, display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||||
<InfoLigneCerfa
|
||||
code="2042"
|
||||
titre="Déclaration des revenus"
|
||||
texte="La déclaration principale : reprend les cases calculées ci-dessus (2TT, 2TR, 2BH, 2CK, 2TY)."
|
||||
/>
|
||||
<InfoLigneCerfa
|
||||
code="2561"
|
||||
titre="IFU — Imprimé fiscal unique"
|
||||
texte="Récapitulatif annuel transmis par les plateformes françaises soumises au prélèvement forfaitaire unique (PFU)."
|
||||
/>
|
||||
{hasEtranger && (
|
||||
<InfoLigneCerfa
|
||||
code="2047"
|
||||
titre="Revenus encaissés à l'étranger"
|
||||
texte="Obligatoire dès qu'une ou plusieurs de vos plateformes sont domiciliées hors de France — détaille les intérêts perçus pays par pays et le crédit d'impôt associé."
|
||||
/>
|
||||
)}
|
||||
{hasEtranger && (
|
||||
<InfoLigneCerfa
|
||||
code="2778-SD"
|
||||
titre="Prélèvement forfaitaire obligatoire (PFO) - selon votre situation fiscale"
|
||||
texte="Les intérêts perçus via des plateformes étrangères sont soumis à un prélèvement forfaitaire obligatoire (acompte) si vous avez un revenu fiscal de référence de l'avant-dernière année de 25 000 € pour un personne seule ou 50 000 € pour couple marié ou pacsé. Malgré la déclaration mensuelle aux autorités fiscales, la déclaration annuelle au travers du CERFA 2047 reste obligatoire."
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ flex: '1 1 320px', minWidth: 280, display: 'flex', justifyContent: 'center' }}>
|
||||
<CerfaFlowDiagram hasEtranger={hasEtranger} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{hasEtranger && (
|
||||
<div style={{
|
||||
marginTop: 14, padding: '12px 14px', borderRadius: 10,
|
||||
background: pfoAssujetti ? 'rgba(16,185,129,0.06)' : 'rgba(245,158,11,0.08)',
|
||||
border: `1px solid ${pfoAssujetti ? 'rgba(16,185,129,0.2)' : 'rgba(245,158,11,0.25)'}`,
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 16, flexWrap: 'wrap',
|
||||
}}>
|
||||
<div style={{ fontSize: 'var(--fs-sm)', lineHeight: 1.5 }}>
|
||||
{pfoAssujetti ? (
|
||||
<>Vous avez des plateformes étrangères et l'option de déclaration <strong>2778-SD</strong> est activée.</>
|
||||
) : (
|
||||
<>Vous avez des plateformes étrangères. Vérifiez si la déclaration mensuelle <strong>2778-SD</strong> s'applique à votre situation.</>
|
||||
)}
|
||||
</div>
|
||||
<button className="btn btn-sm btn-primary" onClick={() => navigate('/settings?section=ma-fiscalite')}>
|
||||
{pfoAssujetti ? 'Gérer dans les paramètres' : 'Vérifier dans les paramètres'}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="text-muted" style={{ marginTop: 14, marginBottom: 0, fontSize: 12, lineHeight: 1.6 }}>
|
||||
⚠ Ce module est une aide à la préparation de votre déclaration ; il ne la remplace pas. Vérifiez chaque montant avant de le reporter.
|
||||
Vous restez seul responsable de l'exactitude de votre déclaration fiscale — Crowdlending ne saurait être tenu responsable des données déclarées.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!detailExpanded && !cerfaExpanded && (
|
||||
<div className="dr-tabs">
|
||||
<button className={`dr-tab${activeTab === '2042' ? ' active' : ''}`} onClick={() => setActiveTab('2042')}>CERFA 2042</button>
|
||||
<button className={`dr-tab${activeTab === 'cerfa' ? ' active' : ''}`} onClick={() => setActiveTab('cerfa')}>CERFA 2561 (IFU)</button>
|
||||
{hasEtranger && <button className={`dr-tab${activeTab === '2047' ? ' active' : ''}`} onClick={() => setActiveTab('2047')}>CERFA 2047</button>}
|
||||
{pfoAssujetti && <button className={`dr-tab${activeTab === '2778' ? ' active' : ''}`} onClick={() => setActiveTab('2778')}>CERFA 2778-SD</button>}
|
||||
</div>
|
||||
)}
|
||||
@@ -324,6 +463,10 @@ export default function TaxReport() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{activeTab === '2047' && hasEtranger && !detailExpanded && !cerfaExpanded && (
|
||||
<Cerfa2047Preview annee={annee} activeView={activeView} />
|
||||
)}
|
||||
|
||||
{activeTab === '2778' && pfoAssujetti && !detailExpanded && !cerfaExpanded && (
|
||||
<Cerfa2778Preview annee={annee} activeView={activeView} />
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user