Découpage des paiements + page de saisie
This commit is contained in:
@@ -62,7 +62,8 @@
|
||||
<option value="{{ a }}" {% if a == annee %}selected{% endif %}>{{ a }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<a href="/admin/"><button type="button">Saisie / Admin</button></a>
|
||||
<a href="/saisie/"><button type="button">+ Saisir un paiement</button></a>
|
||||
<a href="/admin/"><button type="button">Admin</button></a>
|
||||
</form>
|
||||
|
||||
{% if bareme_manquant %}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>JB Compta — Saisie d'un paiement</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; }
|
||||
.sub { color:var(--muted); margin-bottom:20px; }
|
||||
a { color:var(--accent); }
|
||||
.card { background:var(--card); border:1px solid #334155; border-radius:12px;
|
||||
padding:16px; margin-bottom:16px; }
|
||||
label { display:block; font-size:12px; color:var(--muted); margin-bottom:4px; }
|
||||
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;} }
|
||||
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; }
|
||||
td input, td select { padding:6px 8px; }
|
||||
.num { text-align:right; }
|
||||
button { cursor:pointer; border-radius:8px; border:1px solid #334155;
|
||||
background:var(--card); color:var(--txt); padding:8px 14px; font-size:14px; }
|
||||
button.primary { background:var(--accent); color:#04263a; border:none; font-weight:600; }
|
||||
button.mini { padding:4px 8px; }
|
||||
.totaux { display:flex; gap:24px; align-items:center; margin-top:12px; flex-wrap:wrap; }
|
||||
.totaux b { font-size:18px; }
|
||||
.ok{color:var(--ok)} .bad{color:var(--bad)}
|
||||
.msg { padding:10px 14px; border-radius:8px; margin-bottom:10px; }
|
||||
.msg.error { background:#7f1d1d; }
|
||||
.msg.success { background:#064e3b; }
|
||||
.actions { display:flex; gap:12px; margin-top:16px; }
|
||||
</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>
|
||||
|
||||
{% if messages %}
|
||||
{% for m in messages %}
|
||||
<div class="msg {{ m.tags }}">{{ m }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<form method="post" id="frm">
|
||||
{% csrf_token %}
|
||||
<div class="card">
|
||||
<div class="head">
|
||||
<div>
|
||||
<label>Entreprise</label>
|
||||
<select name="entreprise" required>
|
||||
{% for e in entreprises %}<option value="{{ e.pk }}">{{ e.nom }}</option>{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Date</label>
|
||||
<input type="date" name="date" value="{{ today }}">
|
||||
</div>
|
||||
<div>
|
||||
<label>Libellé bancaire</label>
|
||||
<input type="text" name="libelle" placeholder="ex. AMAZON EU SARL" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Montant total payé (€)</label>
|
||||
<input type="number" step="0.01" name="montant_total" id="total"
|
||||
placeholder="150.00" oninput="recalc()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:24%">Libellé / vendeur</th>
|
||||
<th style="width:14%">Catégorie</th>
|
||||
<th style="width:16%">Activité</th>
|
||||
<th style="width:16%">Régime TVA</th>
|
||||
<th style="width:8%">Taux %</th>
|
||||
<th style="width:11%">Montant €</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="totaux">
|
||||
<span>Réparti : <b id="repartis">0.00</b> €</span>
|
||||
<span>Reste : <b id="reste" class="bad">0.00</b> €</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" class="primary">Enregistrer le paiement</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<template id="rowtpl">
|
||||
<tr>
|
||||
<td><input type="text" name="l_libelle" placeholder="Vendeur / objet"></td>
|
||||
<td><input type="text" name="l_categorie" placeholder="ex. Matériel"></td>
|
||||
<td>
|
||||
<select name="l_activite">
|
||||
<option value="">—</option>
|
||||
{% for val,lab in activites %}<option value="{{ val }}">{{ lab }}</option>{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<select name="l_regime">
|
||||
{% for val,lab in regimes %}<option value="{{ val }}">{{ lab }}</option>{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
<td><input type="number" step="0.01" name="l_taux" value="0" class="num"></td>
|
||||
<td><input type="number" step="0.01" name="l_montant" class="num montant" oninput="recalc()"></td>
|
||||
<td><input type="number" step="0.01" name="l_tva" value="0" class="num"></td>
|
||||
<td><button type="button" class="mini" onclick="this.closest('tr').remove();recalc()">✕</button></td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
function addRow(){
|
||||
const tpl = document.getElementById('rowtpl');
|
||||
document.getElementById('lignes').appendChild(tpl.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);
|
||||
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';
|
||||
}
|
||||
// 3 lignes au départ
|
||||
addRow(); addRow(); addRow();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user