Saisie unifiée + 4 vues dashboard (mensuel, déclarations URSSAF/TVA)
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>JB Compta — {% block titre %}Tableau de bord{% endblock %}</title>
|
||||
<style>
|
||||
:root { --bg:#0f172a; --card:#1e293b; --txt:#e2e8f0; --muted:#94a3b8;
|
||||
--accent:#38bdf8; --ok:#34d399; --warn:#fbbf24; --bad:#f87171; }
|
||||
* { box-sizing:border-box; }
|
||||
body { margin:0; font-family:system-ui,Segoe UI,Roboto,sans-serif;
|
||||
background:var(--bg); color:var(--txt); padding:24px; }
|
||||
h1 { margin:0 0 4px; font-size:22px; }
|
||||
h2 { font-size:15px; color:var(--muted); margin:24px 0 10px; font-weight:600; }
|
||||
a { color:var(--accent); text-decoration:none; }
|
||||
.sub { color:var(--muted); margin-bottom:16px; }
|
||||
.nav { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:14px; }
|
||||
.nav a { padding:7px 13px; border-radius:8px; border:1px solid #334155;
|
||||
background:var(--card); font-size:14px; }
|
||||
.nav a.on { background:var(--accent); color:#04263a; border-color:var(--accent); font-weight:600; }
|
||||
.nav a.saisie { margin-left:auto; }
|
||||
form.filters { display:flex; gap:12px; flex-wrap:wrap; margin-bottom:20px; }
|
||||
select, button, input { background:var(--card); color:var(--txt); border:1px solid #334155;
|
||||
border-radius:8px; padding:8px 12px; font-size:14px; }
|
||||
button { cursor:pointer; }
|
||||
.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:16px; margin-bottom:8px; }
|
||||
.card { background:var(--card); border:1px solid #334155; border-radius:12px; padding:16px; }
|
||||
.card .label { color:var(--muted); font-size:13px; }
|
||||
.card .value { font-size:24px; font-weight:600; margin-top:6px; }
|
||||
.card .hint { color:var(--muted); font-size:12px; margin-top:4px; }
|
||||
.ok{color:var(--ok)} .warn{color:var(--warn)} .bad{color:var(--bad)}
|
||||
.bar { height:8px; background:#334155; border-radius:99px; overflow:hidden; margin-top:8px; }
|
||||
.bar > span { display:block; height:100%; background:var(--accent); }
|
||||
.row { display:grid; grid-template-columns:2fr 1fr; gap:16px; margin-top:8px; }
|
||||
@media(max-width:800px){ .row{grid-template-columns:1fr;} }
|
||||
canvas { max-width:100%; }
|
||||
table { width:100%; border-collapse:collapse; font-size:14px; }
|
||||
td,th { padding:8px; border-bottom:1px solid #334155; text-align:right; }
|
||||
th:first-child, td:first-child { text-align:left; }
|
||||
tr.total td { font-weight:600; border-top:2px solid #475569; }
|
||||
.exports a { display:inline-block; margin-right:12px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% if not entreprise %}
|
||||
<h1>Aucune entreprise</h1>
|
||||
<p class="sub">Crée une entreprise dans <a href="/admin/">l'administration</a>,
|
||||
ou <a href="/saisie/">saisis une opération</a>.</p>
|
||||
{% else %}
|
||||
<div class="nav">
|
||||
<a class="{% if vue == 'global' %}on{% endif %}" href="/dashboard/?entreprise={{ entreprise.pk }}&annee={{ annee }}">Global</a>
|
||||
<a class="{% if vue == 'mensuel' %}on{% endif %}" href="/dashboard/mensuel/?entreprise={{ entreprise.pk }}&annee={{ annee }}">Mensuel</a>
|
||||
<a class="{% if vue == 'urssaf' %}on{% endif %}" href="/declaration/urssaf/?entreprise={{ entreprise.pk }}&annee={{ annee }}">Déclaration URSSAF</a>
|
||||
<a class="{% if vue == 'tva' %}on{% endif %}" href="/declaration/tva/?entreprise={{ entreprise.pk }}&annee={{ annee }}">Déclaration TVA</a>
|
||||
<a class="saisie" href="/saisie/">+ Saisir</a>
|
||||
<a href="/admin/">Admin</a>
|
||||
</div>
|
||||
|
||||
<h1>{{ entreprise.nom }}</h1>
|
||||
<div class="sub">{{ entreprise.get_activite_display }} (principale) ·
|
||||
{% if entreprise.franchise_tva %}Franchise de TVA{% else %}Assujetti TVA{% endif %}
|
||||
{% if entreprise.versement_liberatoire %}· Versement libératoire{% endif %}
|
||||
· Exercice {{ annee }}</div>
|
||||
|
||||
<form class="filters" method="get">
|
||||
<select name="entreprise" onchange="this.form.submit()">
|
||||
{% for e in entreprises %}<option value="{{ e.pk }}" {% if e.pk == entreprise.pk %}selected{% endif %}>{{ e.nom }}</option>{% endfor %}
|
||||
</select>
|
||||
<select name="annee" onchange="this.form.submit()">
|
||||
{% for a in annees %}<option value="{{ a }}" {% if a == annee %}selected{% endif %}>{{ a }}</option>{% endfor %}
|
||||
</select>
|
||||
{% block extrafilters %}{% endblock %}
|
||||
</form>
|
||||
|
||||
{% block content %}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,86 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>JB Compta — Tableau de bord</title>
|
||||
<style>
|
||||
:root { --bg:#0f172a; --card:#1e293b; --txt:#e2e8f0; --muted:#94a3b8;
|
||||
--accent:#38bdf8; --ok:#34d399; --warn:#fbbf24; --bad:#f87171; }
|
||||
* { box-sizing:border-box; }
|
||||
body { margin:0; font-family:system-ui,Segoe UI,Roboto,sans-serif;
|
||||
background:var(--bg); color:var(--txt); padding:24px; }
|
||||
h1 { margin:0 0 4px; font-size:22px; }
|
||||
h2 { font-size:15px; color:var(--muted); margin:24px 0 10px; font-weight:600; }
|
||||
a { color:var(--accent); }
|
||||
.sub { color:var(--muted); margin-bottom:20px; }
|
||||
form.filters { display:flex; gap:12px; flex-wrap:wrap; margin-bottom:24px; }
|
||||
select, button { background:var(--card); color:var(--txt); border:1px solid #334155;
|
||||
border-radius:8px; padding:8px 12px; font-size:14px; }
|
||||
button { cursor:pointer; }
|
||||
.grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
|
||||
gap:16px; margin-bottom:8px; }
|
||||
.card { background:var(--card); border:1px solid #334155; border-radius:12px;
|
||||
padding:16px; }
|
||||
.card .label { color:var(--muted); font-size:13px; }
|
||||
.card .value { font-size:26px; font-weight:600; margin-top:6px; }
|
||||
.card .hint { color:var(--muted); font-size:12px; margin-top:4px; }
|
||||
.ok{color:var(--ok)} .warn{color:var(--warn)} .bad{color:var(--bad)}
|
||||
.bar { height:8px; background:#334155; border-radius:99px; overflow:hidden; margin-top:8px;}
|
||||
.bar > span { display:block; height:100%; background:var(--accent); }
|
||||
.row { display:grid; grid-template-columns:2fr 1fr; gap:16px; margin-top:8px; }
|
||||
@media(max-width:800px){ .row{grid-template-columns:1fr;} }
|
||||
.exports a { display:inline-block; margin-right:12px; }
|
||||
canvas { max-width:100%; }
|
||||
table { width:100%; border-collapse:collapse; font-size:14px; }
|
||||
td,th { padding:8px; border-bottom:1px solid #334155; text-align:right; }
|
||||
th:first-child, td:first-child { text-align:left; }
|
||||
tr.total td { font-weight:600; border-top:2px solid #475569; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% if not entreprise %}
|
||||
<h1>Aucune entreprise</h1>
|
||||
<p class="sub">Crée une entreprise et des factures dans
|
||||
<a href="/admin/">l'administration</a>, puis reviens ici.</p>
|
||||
{% else %}
|
||||
<h1>{{ entreprise.nom }}</h1>
|
||||
<div class="sub">{{ entreprise.get_activite_display }} (principale) ·
|
||||
{% if entreprise.franchise_tva %}Franchise de TVA{% else %}Assujetti TVA{% endif %}
|
||||
{% if entreprise.versement_liberatoire %}· Versement libératoire{% endif %}
|
||||
· Exercice {{ annee }}</div>
|
||||
|
||||
<form class="filters" method="get">
|
||||
<select name="entreprise" onchange="this.form.submit()">
|
||||
{% for e in entreprises %}
|
||||
<option value="{{ e.pk }}" {% if e.pk == entreprise.pk %}selected{% endif %}>{{ e.nom }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name="annee" onchange="this.form.submit()">
|
||||
{% for a in annees %}
|
||||
<option value="{{ a }}" {% if a == annee %}selected{% endif %}>{{ a }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<a href="/saisie/"><button type="button">+ Saisir un paiement</button></a>
|
||||
<a href="/admin/"><button type="button">Admin</button></a>
|
||||
</form>
|
||||
{% extends "compta/base.html" %}
|
||||
{% block titre %}Global{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if bareme_manquant %}
|
||||
<div class="card bad" style="margin-bottom:16px;">
|
||||
Une activité avec du CA n'a pas de barème {{ annee }}. Ajoute-le dans
|
||||
<a href="/admin/compta/bareme/">Barèmes</a>.
|
||||
Une activité avec du CA n'a pas de barème {{ annee }}.
|
||||
Ajoute-le dans <a href="/admin/compta/bareme/">Barèmes</a>.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Totaux entreprise -->
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<div class="label">CA HT encaissé (total)</div>
|
||||
<div class="value">{{ ca_ht }} €</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="label">Cotisations URSSAF (total)</div>
|
||||
<div class="label">Cotisations URSSAF</div>
|
||||
<div class="value">{{ cotisations_urssaf|default:"—" }} €</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
@@ -91,93 +26,55 @@
|
||||
<div class="label">TVA à reverser</div>
|
||||
<div class="value">{{ tva_a_reverser }} €</div>
|
||||
<div class="hint">{{ tva_collectee }} collectée − {{ tva_deductible }} déductible</div>
|
||||
{% if tva_autoliquidee %}<div class="hint">dont {{ tva_autoliquidee }} € auto-liquidée (UE/import)</div>{% endif %}
|
||||
{% if tva_autoliquidee %}<div class="hint">dont {{ tva_autoliquidee }} € auto-liquidée</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Ventilation par activité -->
|
||||
<h2>Ventilation par activité</h2>
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Activité</th><th>CA HT</th><th>% plafond</th>
|
||||
<th>URSSAF</th><th>Impôt (VL)</th><th>Revenu imposable</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead><tr><th>Activité</th><th>CA HT</th><th>% plafond</th><th>URSSAF</th><th>Impôt (VL)</th><th>Revenu imposable</th></tr></thead>
|
||||
<tbody>
|
||||
{% for l in lignes_activite %}
|
||||
<tr>
|
||||
<td>{{ l.label }}</td>
|
||||
<td>{{ l.ca_ht }} €</td>
|
||||
<td class="{% if l.depasse_seuil_ca %}bad{% endif %}">
|
||||
{% if l.pct_seuil_ca is not None %}{{ l.pct_seuil_ca }} %{% else %}—{% endif %}
|
||||
</td>
|
||||
<td class="{% if l.depasse_seuil_ca %}bad{% endif %}">{% if l.pct_seuil_ca is not None %}{{ l.pct_seuil_ca }} %{% else %}—{% endif %}</td>
|
||||
<td>{% if l.cotisations is not None %}{{ l.cotisations }} €{% else %}—{% endif %}</td>
|
||||
<td>{% if l.versement_liberatoire is not None %}{{ l.versement_liberatoire }} €{% else %}—{% endif %}</td>
|
||||
<td>{% if l.revenu_imposable is not None %}{{ l.revenu_imposable }} €{% else %}—{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="total">
|
||||
<td>Total</td>
|
||||
<td>{{ ca_ht }} €</td>
|
||||
<td></td>
|
||||
<td>{{ cotisations_urssaf|default:"—" }} €</td>
|
||||
<td>{{ versement_liberatoire|default:"—" }} €</td>
|
||||
<td>{{ revenu_imposable|default:"—" }} €</td>
|
||||
</tr>
|
||||
<tr class="total"><td>Total</td><td>{{ ca_ht }} €</td><td></td><td>{{ cotisations_urssaf|default:"—" }} €</td><td>{{ versement_liberatoire|default:"—" }} €</td><td>{{ revenu_imposable|default:"—" }} €</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Détail TVA -->
|
||||
<h2>TVA</h2>
|
||||
<div class="card">
|
||||
<table>
|
||||
<tr><td>TVA collectée sur ventes</td><td>{{ tva_sur_ventes }} €</td></tr>
|
||||
<tr><td>TVA auto-liquidée (UE / import)</td><td>{{ tva_autoliquidee }} €</td></tr>
|
||||
<tr><td>TVA collectée totale (due)</td><td>{{ tva_collectee }} €</td></tr>
|
||||
<tr><td>TVA déductible</td><td>{{ tva_deductible }} €</td></tr>
|
||||
<tr class="total"><td>TVA à reverser</td><td>{{ tva_a_reverser }} €</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="card">
|
||||
<div class="label" style="margin-bottom:8px;">CA HT mensuel (toutes activités)</div>
|
||||
<div class="label" style="margin-bottom:8px;">CA HT mensuel</div>
|
||||
<canvas id="caChart" height="120"></canvas>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="label" style="margin-bottom:8px;">À provisionner (année)</div>
|
||||
<table>
|
||||
<tr><th>Poste</th><th>Montant</th></tr>
|
||||
<tr><td>URSSAF</td><td>{{ cotisations_urssaf|default:"—" }} €</td></tr>
|
||||
<tr><td>Impôt (VL)</td><td>{{ versement_liberatoire|default:"—" }} €</td></tr>
|
||||
<tr><td>TVA</td><td>{{ tva_a_reverser }} €</td></tr>
|
||||
</table>
|
||||
<div class="exports" style="margin-top:16px;">
|
||||
<div class="label" style="margin-bottom:6px;">Exports CSV</div>
|
||||
<div class="label" style="margin-bottom:8px;">Exports CSV</div>
|
||||
<div class="exports">
|
||||
<a href="{% url 'export_ventes' %}?entreprise={{ entreprise.pk }}&annee={{ annee }}">Ventes</a>
|
||||
<a href="{% url 'export_tva' %}?entreprise={{ entreprise.pk }}&annee={{ annee }}">TVA</a>
|
||||
<a href="{% url 'export_urssaf' %}?entreprise={{ entreprise.pk }}&annee={{ annee }}">URSSAF</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
const ctx = document.getElementById('caChart');
|
||||
new Chart(ctx, {
|
||||
new Chart(document.getElementById('caChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: {{ mois_labels|safe }},
|
||||
datasets: [{ label: 'CA HT (€)', data: {{ ca_mensuel_json|safe }},
|
||||
backgroundColor: '#38bdf8' }]
|
||||
},
|
||||
data: { labels: {{ mois_labels|safe }},
|
||||
datasets: [{ label:'CA HT (€)', data: {{ ca_mensuel_json|safe }}, backgroundColor:'#38bdf8' }] },
|
||||
options: { plugins:{legend:{display:false}},
|
||||
scales:{ x:{ticks:{color:'#94a3b8'}}, y:{ticks:{color:'#94a3b8'}} } }
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
{% extends "compta/base.html" %}
|
||||
{% block titre %}Déclaration TVA{% endblock %}
|
||||
|
||||
{% block extrafilters %}
|
||||
<select name="mois" onchange="this.form.submit()">
|
||||
{% for num, nom in mois_liste %}
|
||||
<option value="{{ num }}" {% if num == mois_sel %}selected{% endif %}>{{ nom }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Déclaration TVA — {{ decl.mois_nom }} {{ annee }}</h2>
|
||||
<div class="sub">
|
||||
Mode :
|
||||
<a href="/declaration/tva/?entreprise={{ entreprise.pk }}&annee={{ annee }}&mois={{ mois_sel }}&mode=simplifie"
|
||||
{% if mode != 'ca3' %}class="on" style="padding:2px 8px;border-radius:6px;"{% endif %}>Résumé</a> ·
|
||||
<a href="/declaration/tva/?entreprise={{ entreprise.pk }}&annee={{ annee }}&mois={{ mois_sel }}&mode=ca3"
|
||||
{% if mode == 'ca3' %}class="on" style="padding:2px 8px;border-radius:6px;"{% endif %}>Champs CA3</a>
|
||||
(réglage par défaut de l'entreprise : {{ entreprise.get_vue_tva_display }})
|
||||
</div>
|
||||
|
||||
{% if mode == 'ca3' %}
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead><tr><th>Ligne CA3</th><th>Libellé</th><th>Base HT</th><th>TVA</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>01</td><td>Ventes / prestations taxables</td><td>{{ decl.ca3.l01_base_taxable }} €</td><td></td></tr>
|
||||
<tr><td>08</td><td>Taux normal 20 %</td><td>{{ decl.ca3.l08_base }} €</td><td>{{ decl.ca3.l08_tva }} €</td></tr>
|
||||
<tr><td>9B</td><td>Taux réduit 10 %</td><td>{{ decl.ca3.l9B_base }} €</td><td>{{ decl.ca3.l9B_tva }} €</td></tr>
|
||||
<tr><td>09</td><td>Taux réduit 5,5 %</td><td>{{ decl.ca3.l09_base }} €</td><td>{{ decl.ca3.l09_tva }} €</td></tr>
|
||||
<tr><td>03</td><td>Acquisitions intracommunautaires</td><td>{{ decl.ca3.l03_intra_base }} €</td><td></td></tr>
|
||||
<tr><td>17</td><td>dont TVA sur acquisitions intracom</td><td></td><td>{{ decl.ca3.l17_intra_tva }} €</td></tr>
|
||||
<tr class="total"><td>16</td><td>TVA brute due</td><td></td><td>{{ decl.ca3.l16_tva_brute }} €</td></tr>
|
||||
<tr><td>20</td><td>TVA déductible (biens et services)</td><td></td><td>{{ decl.ca3.l20_tva_deductible }} €</td></tr>
|
||||
<tr class="total"><td>28</td><td>Total TVA déductible</td><td></td><td>{{ decl.ca3.l28_total_deductible }} €</td></tr>
|
||||
<tr class="total"><td>32</td><td>TVA à payer</td><td></td><td>{{ decl.ca3.l32_a_payer }} €</td></tr>
|
||||
{% if decl.ca3.l25_credit %}<tr class="total"><td>25</td><td>Crédit de TVA</td><td></td><td>{{ decl.ca3.l25_credit }} €</td></tr>{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="sub">Numéros de lignes du formulaire 3310-CA3 (régime réel normal). À recouper
|
||||
avec ta déclaration officielle — vérifie notamment la ventilation par taux.</div>
|
||||
{% else %}
|
||||
<div class="grid">
|
||||
<div class="card"><div class="label">TVA collectée sur ventes</div><div class="value">{{ decl.tva_sur_ventes }} €</div></div>
|
||||
<div class="card"><div class="label">TVA auto-liquidée (UE/import)</div><div class="value">{{ decl.tva_autoliquidee }} €</div></div>
|
||||
<div class="card"><div class="label">TVA collectée totale</div><div class="value">{{ decl.tva_collectee }} €</div></div>
|
||||
<div class="card"><div class="label">TVA déductible</div><div class="value">{{ decl.tva_deductible }} €</div></div>
|
||||
<div class="card">
|
||||
<div class="label">{% if decl.credit_tva %}Crédit de TVA{% else %}TVA à payer{% endif %}</div>
|
||||
<div class="value {% if decl.credit_tva %}ok{% endif %}">{% if decl.credit_tva %}{{ decl.credit_tva }}{% else %}{{ decl.tva_a_payer }}{% endif %} €</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if decl.par_taux %}
|
||||
<h2>Détail par taux (ventes)</h2>
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead><tr><th>Taux</th><th>Base HT</th><th>TVA</th></tr></thead>
|
||||
<tbody>
|
||||
{% for t in decl.par_taux %}<tr><td>{{ t.taux }} %</td><td>{{ t.base }} €</td><td>{{ t.tva }} €</td></tr>{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,43 @@
|
||||
{% extends "compta/base.html" %}
|
||||
{% block titre %}Déclaration URSSAF{% endblock %}
|
||||
|
||||
{% block extrafilters %}
|
||||
<select name="mois" onchange="this.form.submit()">
|
||||
{% for num, nom in mois_liste %}
|
||||
<option value="{{ num }}" {% if num == mois_sel %}selected{% endif %}>{{ nom }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Déclaration URSSAF — {{ decl.mois_nom }} {{ annee }}</h2>
|
||||
<div class="sub">À déclarer sur autoentrepreneur.urssaf.fr : le CA HT encaissé de la période,
|
||||
par type d'activité. Les cotisations (et l'impôt si versement libératoire) en découlent.</div>
|
||||
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Activité</th><th>CA HT à déclarer</th><th>Taux URSSAF</th><th>Cotisations</th>
|
||||
{% if decl.versement_liberatoire is not None %}<th>Taux VL</th><th>Impôt (VL)</th>{% endif %}</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for l in decl.lignes %}
|
||||
<tr>
|
||||
<td>{{ l.label }}</td>
|
||||
<td>{{ l.ca_ht }} €</td>
|
||||
<td>{% if l.taux_urssaf is not None %}{{ l.taux_urssaf }} %{% else %}—{% endif %}</td>
|
||||
<td>{% if l.cotisations is not None %}{{ l.cotisations }} €{% else %}—{% endif %}</td>
|
||||
{% if decl.versement_liberatoire is not None %}
|
||||
<td>{% if l.taux_vl is not None %}{{ l.taux_vl }} %{% else %}—{% endif %}</td>
|
||||
<td>{% if l.versement_liberatoire is not None %}{{ l.versement_liberatoire }} €{% else %}—{% endif %}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="total">
|
||||
<td>Total</td><td>{{ decl.ca_ht }} €</td><td></td><td>{{ decl.cotisations|default:"—" }} €</td>
|
||||
{% if decl.versement_liberatoire is not None %}<td></td><td>{{ decl.versement_liberatoire }} €</td>{% endif %}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,29 @@
|
||||
{% extends "compta/base.html" %}
|
||||
{% block titre %}Mensuel{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Vue mensuelle {{ annee }}</h2>
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Mois</th><th>CA HT</th><th>Cotisations URSSAF</th>
|
||||
<th>Impôt (VL)</th><th>TVA collectée</th><th>TVA déductible</th><th>TVA à reverser</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for r in rows %}
|
||||
<tr>
|
||||
<td>{{ r.nom }}</td>
|
||||
<td>{{ r.ca_ht }} €</td>
|
||||
<td>{{ r.cotisations }} €</td>
|
||||
<td>{% if r.versement_liberatoire is not None %}{{ r.versement_liberatoire }} €{% else %}—{% endif %}</td>
|
||||
<td>{{ r.tva_collectee }} €</td>
|
||||
<td>{{ r.tva_deductible }} €</td>
|
||||
<td>{{ r.tva_a_reverser }} €</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>JB Compta — Saisie d'un paiement</title>
|
||||
<title>JB Compta — Saisie</title>
|
||||
<style>
|
||||
:root { --bg:#0f172a; --card:#1e293b; --txt:#e2e8f0; --muted:#94a3b8;
|
||||
--accent:#38bdf8; --ok:#34d399; --warn:#fbbf24; --bad:#f87171; }
|
||||
@@ -19,7 +19,8 @@
|
||||
input, select { background:#0f172a; color:var(--txt); border:1px solid #334155;
|
||||
border-radius:8px; padding:8px 10px; font-size:14px; width:100%; }
|
||||
.head { display:grid; grid-template-columns:1fr 1fr 2fr 1fr; gap:12px; }
|
||||
@media(max-width:700px){ .head{grid-template-columns:1fr 1fr;} }
|
||||
.grid2 { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
|
||||
@media(max-width:700px){ .head,.grid2{grid-template-columns:1fr;} }
|
||||
table { width:100%; border-collapse:collapse; font-size:13px; margin-top:8px; }
|
||||
th,td { padding:6px; border-bottom:1px solid #334155; text-align:left; vertical-align:top; }
|
||||
th { color:var(--muted); font-weight:600; }
|
||||
@@ -36,19 +37,19 @@
|
||||
.msg.error { background:#7f1d1d; }
|
||||
.msg.success { background:#064e3b; }
|
||||
.actions { display:flex; gap:12px; margin-top:16px; }
|
||||
.badge { display:inline-block; padding:2px 10px; border-radius:99px; font-size:12px; }
|
||||
.badge.dep { background:#7f1d1d; }
|
||||
.badge.ven { background:#064e3b; }
|
||||
.hidden { display:none; }
|
||||
.hint { color:var(--muted); font-size:12px; margin-top:6px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Saisie d'un paiement</h1>
|
||||
<div class="sub">Éclate une opération bancaire (ex. un débit Amazon groupé) en
|
||||
plusieurs dépenses. · <a href="/dashboard/">← Tableau de bord</a> ·
|
||||
<a href="/admin/compta/depense/">Voir les dépenses</a></div>
|
||||
<h1>Saisie d'une opération</h1>
|
||||
<div class="sub">Montant <b>négatif</b> = dépense · <b>positif</b> = vente/encaissement.
|
||||
· <a href="/dashboard/">← Tableau de bord</a></div>
|
||||
|
||||
{% if messages %}
|
||||
{% for m in messages %}
|
||||
<div class="msg {{ m.tags }}">{{ m }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if messages %}{% for m in messages %}<div class="msg {{ m.tags }}">{{ m }}</div>{% endfor %}{% endif %}
|
||||
|
||||
<form method="post" id="frm">
|
||||
{% csrf_token %}
|
||||
@@ -66,45 +67,85 @@
|
||||
</div>
|
||||
<div>
|
||||
<label>Libellé bancaire</label>
|
||||
<input type="text" name="libelle" placeholder="ex. AMAZON EU SARL" required>
|
||||
<input type="text" name="libelle" placeholder="ex. AMAZON / ALTISSIMO" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Montant total payé (€)</label>
|
||||
<label>Montant signé (€) <span id="badge"></span></label>
|
||||
<input type="number" step="0.01" name="montant_total" id="total"
|
||||
placeholder="150.00" oninput="recalc()">
|
||||
placeholder="-150 ou 168.40" oninput="toggle()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<!-- ===== PANEL DÉPENSE (montant négatif) ===== -->
|
||||
<div class="card hidden" id="panel-depense">
|
||||
<div class="sub" style="margin:0 0 8px">Dépense — éclate en une ou plusieurs lignes.</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:22%">Libellé / vendeur</th>
|
||||
<th style="width:16%">Catégorie</th>
|
||||
<th style="width:15%">Activité</th>
|
||||
<th style="width:15%">Régime TVA</th>
|
||||
<th style="width:14%">Activité</th>
|
||||
<th style="width:16%">Régime TVA</th>
|
||||
<th style="width:7%">Taux %</th>
|
||||
<th style="width:11%">Montant €</th>
|
||||
<th style="width:11%">TVA déduct. €</th>
|
||||
<th style="width:11%">TVA déduct.</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="lignes"></tbody>
|
||||
</table>
|
||||
|
||||
<div class="actions">
|
||||
<button type="button" onclick="addRow()">+ Ajouter une ligne</button>
|
||||
</div>
|
||||
|
||||
<div class="actions"><button type="button" onclick="addRow()">+ Ajouter une ligne</button></div>
|
||||
<div class="totaux">
|
||||
<span>Réparti : <b id="repartis">0.00</b> €</span>
|
||||
<span>Reste : <b id="reste" class="bad">0.00</b> €</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== PANEL VENTE (montant positif) ===== -->
|
||||
<div class="card hidden" id="panel-vente">
|
||||
<div class="sub" style="margin:0 0 8px">Vente — crée une facture encaissée (ou un mouvement neutre).</div>
|
||||
<div class="grid2">
|
||||
<div>
|
||||
<label>Client existant</label>
|
||||
<select name="v_client">
|
||||
<option value="">—</option>
|
||||
{% for c in clients %}<option value="{{ c.pk }}">{{ c.nom }} ({{ c.entreprise.nom }})</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>…ou nouveau client</label>
|
||||
<input type="text" name="v_client_nouveau" placeholder="Nom du nouveau client">
|
||||
</div>
|
||||
<div>
|
||||
<label>Activité</label>
|
||||
<select name="v_activite">
|
||||
{% for val,lab in activites %}<option value="{{ val }}">{{ lab }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Taux TVA (%)</label>
|
||||
<input type="number" step="0.01" name="v_taux" value="20">
|
||||
</div>
|
||||
<div>
|
||||
<label>Désignation</label>
|
||||
<input type="text" name="v_designation" placeholder="ex. Vente de produits finis">
|
||||
</div>
|
||||
<div>
|
||||
<label>Ou catégorie neutre (ex. remboursement TVA)</label>
|
||||
<select name="v_categorie">
|
||||
<option value="">— (vente normale)</option>
|
||||
{% for c in categories_vente %}<option value="{{ c.pk }}">{{ c.nom }}{% if c.exclure_calculs %} (neutre){% endif %}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">Le montant TTC encaissé = le montant signé saisi plus haut. HT et TVA
|
||||
sont calculés depuis le taux. Si tu choisis une catégorie <b>neutre</b>, aucune facture
|
||||
n'est créée (simple mouvement de trésorerie).</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" class="primary">Enregistrer le paiement</button>
|
||||
<button type="submit" class="primary">Enregistrer</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -114,7 +155,7 @@
|
||||
<td>
|
||||
<select name="l_categorie">
|
||||
<option value="">—</option>
|
||||
{% for c in categories %}<option value="{{ c.pk }}">{{ c.nom }}</option>{% endfor %}
|
||||
{% for c in categories_depense %}<option value="{{ c.pk }}">{{ c.nom }}</option>{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
@@ -137,20 +178,32 @@
|
||||
|
||||
<script>
|
||||
function addRow(){
|
||||
const tpl = document.getElementById('rowtpl');
|
||||
document.getElementById('lignes').appendChild(tpl.content.cloneNode(true));
|
||||
document.getElementById('lignes').appendChild(
|
||||
document.getElementById('rowtpl').content.cloneNode(true));
|
||||
}
|
||||
function recalc(){
|
||||
let s = 0;
|
||||
document.querySelectorAll('.montant').forEach(i => s += parseFloat(i.value||0));
|
||||
const total = parseFloat(document.getElementById('total').value||0);
|
||||
const total = Math.abs(parseFloat(document.getElementById('total').value||0));
|
||||
document.getElementById('repartis').textContent = s.toFixed(2);
|
||||
const reste = (total - s);
|
||||
const el = document.getElementById('reste');
|
||||
el.textContent = reste.toFixed(2);
|
||||
el.className = Math.abs(reste) < 0.01 ? 'ok' : 'bad';
|
||||
}
|
||||
addRow(); addRow(); addRow();
|
||||
function toggle(){
|
||||
const v = parseFloat(document.getElementById('total').value||0);
|
||||
const dep = document.getElementById('panel-depense');
|
||||
const ven = document.getElementById('panel-vente');
|
||||
const badge = document.getElementById('badge');
|
||||
if (v < 0){ dep.classList.remove('hidden'); ven.classList.add('hidden');
|
||||
badge.className='badge dep'; badge.textContent='Dépense';
|
||||
if(!document.querySelector('#lignes tr')){addRow();addRow();}
|
||||
recalc(); }
|
||||
else if (v > 0){ ven.classList.remove('hidden'); dep.classList.add('hidden');
|
||||
badge.className='badge ven'; badge.textContent='Vente'; }
|
||||
else { dep.classList.add('hidden'); ven.classList.add('hidden'); badge.textContent=''; }
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user