""" 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, }