100 lines
3.8 KiB
Python
100 lines
3.8 KiB
Python
"""
|
|
Page de saisie / import : éclater un paiement bancaire en plusieurs dépenses.
|
|
"""
|
|
from decimal import Decimal, InvalidOperation
|
|
from datetime import date
|
|
|
|
from django.contrib import messages
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.shortcuts import render, redirect
|
|
|
|
from .models import Entreprise, Paiement, Depense, Activite, RegimeTva
|
|
|
|
|
|
def _dec(val, defaut="0"):
|
|
try:
|
|
return Decimal((val or defaut).replace(",", ".").strip() or defaut)
|
|
except (InvalidOperation, AttributeError):
|
|
return Decimal(defaut)
|
|
|
|
|
|
@login_required
|
|
def saisie_paiement(request):
|
|
entreprises = Entreprise.objects.all()
|
|
|
|
if request.method == "POST":
|
|
entreprise = entreprises.filter(pk=request.POST.get("entreprise")).first()
|
|
d = request.POST.get("date") or date.today().isoformat()
|
|
libelle = (request.POST.get("libelle") or "").strip()
|
|
montant_total = _dec(request.POST.get("montant_total"))
|
|
|
|
libelles = request.POST.getlist("l_libelle")
|
|
categories = request.POST.getlist("l_categorie")
|
|
activites = request.POST.getlist("l_activite")
|
|
regimes = request.POST.getlist("l_regime")
|
|
taux = request.POST.getlist("l_taux")
|
|
montants = request.POST.getlist("l_montant")
|
|
tvas = request.POST.getlist("l_tva")
|
|
|
|
lignes = []
|
|
for i in range(len(libelles)):
|
|
m = _dec(montants[i] if i < len(montants) else "0")
|
|
lib = (libelles[i] or "").strip()
|
|
if m == 0 and not lib:
|
|
continue # ligne vide ignorée
|
|
lignes.append({
|
|
"libelle": lib or "(sans libellé)",
|
|
"categorie": categories[i] if i < len(categories) else "",
|
|
"activite": activites[i] if i < len(activites) else "",
|
|
"regime": regimes[i] if i < len(regimes) else RegimeTva.NATIONALE,
|
|
"taux": _dec(taux[i] if i < len(taux) else "0"),
|
|
"montant": m,
|
|
"tva": _dec(tvas[i] if i < len(tvas) else "0"),
|
|
})
|
|
|
|
somme = sum((l["montant"] for l in lignes), Decimal("0"))
|
|
erreurs = []
|
|
if not entreprise:
|
|
erreurs.append("Sélectionne une entreprise.")
|
|
if not libelle:
|
|
erreurs.append("Renseigne le libellé du paiement.")
|
|
if not lignes:
|
|
erreurs.append("Ajoute au moins une ligne de dépense.")
|
|
if lignes and abs(somme - montant_total) >= Decimal("0.01"):
|
|
erreurs.append(
|
|
f"La somme des lignes ({somme} €) ne correspond pas au "
|
|
f"montant total ({montant_total} €). Écart : {somme - montant_total} €.")
|
|
|
|
if erreurs:
|
|
for e in erreurs:
|
|
messages.error(request, e)
|
|
return render(request, "compta/saisie_paiement.html",
|
|
_context(entreprises, request.POST))
|
|
|
|
paiement = Paiement.objects.create(
|
|
entreprise=entreprise, date=d, libelle=libelle,
|
|
montant_total=montant_total, sens="debit")
|
|
for l in lignes:
|
|
Depense.objects.create(
|
|
entreprise=entreprise, paiement=paiement, date=d,
|
|
libelle=l["libelle"], categorie=l["categorie"],
|
|
activite=l["activite"] or "", regime_tva=l["regime"],
|
|
taux_tva=l["taux"], montant_ttc=l["montant"], montant_tva=l["tva"])
|
|
|
|
messages.success(
|
|
request,
|
|
f"Paiement « {libelle} » enregistré et éclaté en {len(lignes)} dépense(s).")
|
|
return redirect("saisie_paiement")
|
|
|
|
return render(request, "compta/saisie_paiement.html", _context(entreprises))
|
|
|
|
|
|
def _context(entreprises, post=None):
|
|
return {
|
|
"entreprises": entreprises,
|
|
"activites": Activite.choices,
|
|
"regimes": RegimeTva.choices,
|
|
"today": date.today().isoformat(),
|
|
"post": post,
|
|
}
|