Taux TVA auto + seed enrichi + import photo collee
This commit is contained in:
+3
-8
@@ -28,8 +28,6 @@ class ScopedAdmin(admin.ModelAdmin):
|
||||
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
||||
|
||||
|
||||
# ----- Référentiels mutualisés (visibles par tous) -----
|
||||
|
||||
@admin.register(Categorie)
|
||||
class CategorieAdmin(admin.ModelAdmin):
|
||||
list_display = ("nom", "usage", "exclure_calculs", "actif", "ordre")
|
||||
@@ -45,8 +43,6 @@ class BaremeAdmin(admin.ModelAdmin):
|
||||
list_filter = ("annee", "activite")
|
||||
|
||||
|
||||
# ----- Entreprise (accès) -----
|
||||
|
||||
@admin.register(Entreprise)
|
||||
class EntrepriseAdmin(admin.ModelAdmin):
|
||||
list_display = ("nom", "activite", "franchise_tva", "versement_liberatoire",
|
||||
@@ -62,14 +58,11 @@ class EntrepriseAdmin(admin.ModelAdmin):
|
||||
return Entreprise.accessibles(request.user)
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
# Seul un superadmin gère les droits d'accès.
|
||||
if not request.user.is_superuser:
|
||||
return ("utilisateurs", "groupes")
|
||||
return ()
|
||||
|
||||
|
||||
# ----- Données cloisonnées par entreprise -----
|
||||
|
||||
@admin.register(Client)
|
||||
class ClientAdmin(ScopedAdmin):
|
||||
list_display = ("nom", "entreprise", "email", "siret")
|
||||
@@ -108,6 +101,7 @@ class DepenseInline(admin.TabularInline):
|
||||
extra = 0
|
||||
fields = ("date", "libelle", "categorie", "activite", "regime_tva",
|
||||
"taux_tva", "montant_ttc", "montant_tva")
|
||||
readonly_fields = ("montant_tva",)
|
||||
|
||||
|
||||
@admin.register(Paiement)
|
||||
@@ -135,10 +129,11 @@ class PaiementAdmin(ScopedAdmin):
|
||||
@admin.register(Depense)
|
||||
class DepenseAdmin(ScopedAdmin):
|
||||
list_display = ("date", "entreprise", "libelle", "categorie", "activite",
|
||||
"regime_tva", "montant_ttc", "montant_tva", "tva_autoliq", "paiement")
|
||||
"regime_tva", "taux_tva", "montant_ttc", "montant_tva", "tva_autoliq", "paiement")
|
||||
list_filter = ("entreprise", "categorie", "regime_tva", "activite", "date")
|
||||
search_fields = ("libelle",)
|
||||
date_hierarchy = "date"
|
||||
readonly_fields = ("montant_tva",)
|
||||
|
||||
@admin.display(description="TVA auto-liquidée")
|
||||
def tva_autoliq(self, obj):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Charge les données de RÉFÉRENCE (barèmes + catégories) puis un jeu de
|
||||
données d'EXEMPLE (entreprise, clients, factures, dépenses).
|
||||
Pour la prod, préférez `seed_reference` (référence seule, sans démo).
|
||||
Référence (barèmes + catégories + groupe) PUIS un jeu de données d'exemple
|
||||
couvrant tous les modèles : entreprise, clients, factures + lignes, dépenses,
|
||||
et opérations bancaires (débit éclaté, crédit neutre).
|
||||
|
||||
Usage : python manage.py seed_demo
|
||||
"""
|
||||
@@ -11,14 +11,14 @@ from datetime import date
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from compta.models import (
|
||||
Entreprise, Client, Facture, LigneFacture, Depense, Activite,
|
||||
Entreprise, Client, Facture, LigneFacture, Depense, Paiement, Activite,
|
||||
StatutFacture, RegimeTva,
|
||||
)
|
||||
from compta.management.commands.seed_reference import charger_reference
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Charge la référence + des données d'exemple."
|
||||
help = "Charge la référence + des données d'exemple (tous les modèles)."
|
||||
|
||||
def handle(self, *args, **options):
|
||||
cat = charger_reference(self.stdout, self.style)
|
||||
@@ -26,16 +26,14 @@ class Command(BaseCommand):
|
||||
ent, _ = Entreprise.objects.get_or_create(
|
||||
nom="JB Conseil",
|
||||
defaults=dict(activite=Activite.SERVICE_BIC, franchise_tva=False,
|
||||
taux_tva_defaut=Decimal("20.00"),
|
||||
versement_liberatoire=True, email="jb@example.fr",
|
||||
num_tva_intracom="FR00123456789"))
|
||||
taux_tva_defaut=Decimal("20.00"), versement_liberatoire=True,
|
||||
email="jb@example.fr", num_tva_intracom="FR00123456789"))
|
||||
|
||||
clients = {}
|
||||
for nom, mail in [("Acme SARL", "contact@acme.fr"),
|
||||
("Studio Lumiere", "hello@studiolumiere.fr"),
|
||||
("Mairie de Ville", "compta@ville.fr")]:
|
||||
c, _ = Client.objects.get_or_create(entreprise=ent, nom=nom,
|
||||
defaults=dict(email=mail))
|
||||
c, _ = Client.objects.get_or_create(entreprise=ent, nom=nom, defaults=dict(email=mail))
|
||||
clients[nom] = c
|
||||
|
||||
V, S = Activite.VENTE, Activite.SERVICE_BIC
|
||||
@@ -55,32 +53,44 @@ class Command(BaseCommand):
|
||||
f, created = Facture.objects.get_or_create(
|
||||
entreprise=ent, numero=numero,
|
||||
defaults=dict(client=clients[client_nom], activite=activite,
|
||||
date_emission=emis, date_encaissement=enc,
|
||||
statut=statut))
|
||||
date_emission=emis, date_encaissement=enc, statut=statut))
|
||||
if created:
|
||||
for des, qte, pu in lignes:
|
||||
LigneFacture.objects.create(
|
||||
facture=f, designation=des, quantite=Decimal(qte),
|
||||
prix_unitaire_ht=Decimal(pu), taux_tva=Decimal("20"))
|
||||
LigneFacture.objects.create(facture=f, designation=des, quantite=Decimal(qte),
|
||||
prix_unitaire_ht=Decimal(pu), taux_tva=Decimal("20"))
|
||||
f.recompute_totaux()
|
||||
|
||||
Depense.objects.get_or_create(
|
||||
entreprise=ent, libelle="Bobines PLA/PETG", date=date(2026, 1, 15),
|
||||
defaults=dict(categorie=cat["Matière première"], activite=Activite.VENTE,
|
||||
montant_ttc=Decimal("96.00"), montant_tva=Decimal("16.00")))
|
||||
Depense.objects.get_or_create(
|
||||
entreprise=ent, libelle="Abonnement outils", date=date(2026, 2, 10),
|
||||
defaults=dict(categorie=cat["Abonnement logiciel"],
|
||||
activite=Activite.SERVICE_BIC,
|
||||
montant_ttc=Decimal("34.80"), montant_tva=Decimal("5.80")))
|
||||
Depense.objects.get_or_create(
|
||||
entreprise=ent, libelle="Imprimante 3D (DE)", date=date(2026, 2, 20),
|
||||
defaults=dict(categorie=cat["Matériel et outillage"], activite=Activite.VENTE,
|
||||
regime_tva=RegimeTva.INTRACOM, taux_tva=Decimal("20"),
|
||||
montant_ttc=Decimal("500.00"), montant_tva=Decimal("0")))
|
||||
Depense.objects.get_or_create(
|
||||
entreprise=ent, libelle="URSSAF DE LORRAINE", date=date(2026, 3, 3),
|
||||
defaults=dict(categorie=cat["Cotisation sociale Urssaf"],
|
||||
montant_ttc=Decimal("73.00"), montant_tva=Decimal("0")))
|
||||
def depense(libelle, jour, montant_ttc, cat_nom, taux="20",
|
||||
regime=RegimeTva.NATIONALE, activite="", paiement=None):
|
||||
# montant_tva est calculé automatiquement dans Depense.save().
|
||||
Depense.objects.get_or_create(
|
||||
entreprise=ent, libelle=libelle, date=date(2026, *jour),
|
||||
defaults=dict(categorie=cat[cat_nom], activite=activite, paiement=paiement,
|
||||
regime_tva=regime, taux_tva=Decimal(taux),
|
||||
montant_ttc=Decimal(montant_ttc)))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS("Données d'exemple chargées."))
|
||||
# Opération bancaire DÉBIT éclatée : un paiement Amazon = 2 dépenses
|
||||
amazon, _ = Paiement.objects.get_or_create(
|
||||
entreprise=ent, libelle="AMAZON PAYMENTS", date=date(2026, 6, 22),
|
||||
defaults=dict(montant_total=Decimal("24.52"), sens="debit"))
|
||||
depense("Amazon - visserie", (6, 22), "15.82", "Matériel et outillage",
|
||||
activite=Activite.VENTE, paiement=amazon)
|
||||
depense("Amazon - filament", (6, 18), "8.70", "Matériel et outillage",
|
||||
activite=Activite.VENTE, paiement=amazon)
|
||||
|
||||
# Dépenses variées (taux 20 / 10 / intracom / neutre)
|
||||
depense("Bobines PLA/PETG", (1, 15), "96.00", "Matière première", activite=Activite.VENTE)
|
||||
depense("Burger King", (6, 11), "16.15", "Frais de repas hors domicile", taux="10")
|
||||
depense("Abonnement outils", (2, 10), "34.80", "Abonnement logiciel",
|
||||
activite=Activite.SERVICE_BIC)
|
||||
depense("Imprimante 3D (DE)", (2, 20), "500.00", "Matériel et outillage",
|
||||
regime=RegimeTva.INTRACOM, activite=Activite.VENTE)
|
||||
depense("URSSAF DE LORRAINE", (6, 3), "73.00", "Cotisation sociale Urssaf", taux="0")
|
||||
|
||||
# Opération bancaire CRÉDIT neutre : remboursement de TVA
|
||||
Paiement.objects.get_or_create(
|
||||
entreprise=ent, libelle="SIE EPINAL", date=date(2026, 6, 15),
|
||||
defaults=dict(montant_total=Decimal("103.00"), sens="credit",
|
||||
categorie=cat["Remboursement de TVA"]))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS("Données d'exemple chargées (tous les modèles)."))
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.2.15 on 2026-06-30 07:05
|
||||
|
||||
from decimal import Decimal
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('compta', '0007_alter_paiement_options_entreprise_groupes_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='depense',
|
||||
name='montant_tva',
|
||||
field=models.DecimalField(decimal_places=2, default=Decimal('0'), help_text='Calculée automatiquement depuis le montant payé et le taux.', max_digits=12, verbose_name='TVA déductible (€)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='depense',
|
||||
name='taux_tva',
|
||||
field=models.DecimalField(choices=[(Decimal('0'), '0 %'), (Decimal('5.5'), '5,5 %'), (Decimal('10'), '10 %'), (Decimal('20'), '20 %')], decimal_places=2, default=Decimal('20'), help_text='Achat national : la TVA déductible est calculée. UE/import : taux auto-liquidé.', max_digits=4, verbose_name='Taux de TVA (%)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='lignefacture',
|
||||
name='taux_tva',
|
||||
field=models.DecimalField(choices=[(Decimal('0'), '0 %'), (Decimal('5.5'), '5,5 %'), (Decimal('10'), '10 %'), (Decimal('20'), '20 %')], decimal_places=2, default=Decimal('0'), max_digits=4),
|
||||
),
|
||||
]
|
||||
+23
-7
@@ -27,6 +27,10 @@ class RegimeTva(models.TextChoices):
|
||||
IMPORT = "import", "Import hors UE (autoliquidation)"
|
||||
|
||||
|
||||
TAUX_TVA_CHOICES = [(Decimal("0"), "0 %"), (Decimal("5.5"), "5,5 %"),
|
||||
(Decimal("10"), "10 %"), (Decimal("20"), "20 %")]
|
||||
|
||||
|
||||
class Categorie(models.Model):
|
||||
"""Catégorie globale (mutualisée). exclure_calculs=True => mouvement neutre."""
|
||||
USAGE = [("depense", "Dépense"), ("vente", "Vente"), ("neutre", "Mouvement neutre")]
|
||||
@@ -84,7 +88,6 @@ class Entreprise(models.Model):
|
||||
num_tva_intracom = models.CharField("N° TVA intracommunautaire", max_length=20, blank=True)
|
||||
vue_tva = models.CharField(
|
||||
"Mode d'affichage de la déclaration TVA", max_length=10, choices=VUE_TVA, default="simplifie")
|
||||
# --- Droits d'accès (multi-utilisateur) ---
|
||||
utilisateurs = models.ManyToManyField(
|
||||
settings.AUTH_USER_MODEL, blank=True, related_name="entreprises",
|
||||
verbose_name="Utilisateurs autorisés",
|
||||
@@ -110,7 +113,6 @@ class Entreprise(models.Model):
|
||||
|
||||
@classmethod
|
||||
def accessibles(cls, user):
|
||||
"""Entreprises visibles par un utilisateur (toutes si superadmin)."""
|
||||
if not user or not user.is_authenticated:
|
||||
return cls.objects.none()
|
||||
if user.is_superuser:
|
||||
@@ -179,7 +181,8 @@ class LigneFacture(models.Model):
|
||||
designation = models.CharField(max_length=255)
|
||||
quantite = models.DecimalField(max_digits=12, decimal_places=3, default=Decimal("1"))
|
||||
prix_unitaire_ht = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
taux_tva = models.DecimalField(max_digits=4, decimal_places=2, default=Decimal("0"))
|
||||
taux_tva = models.DecimalField(max_digits=4, decimal_places=2, default=Decimal("0"),
|
||||
choices=TAUX_TVA_CHOICES)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Ligne de facture"
|
||||
@@ -244,13 +247,14 @@ class Depense(models.Model):
|
||||
"Montant payé (€)", max_digits=12, decimal_places=2,
|
||||
help_text="Pour un achat UE/import, c'est le montant HT (sans TVA facturée).")
|
||||
montant_tva = models.DecimalField(
|
||||
"TVA déductible facturée (€)", max_digits=12, decimal_places=2, default=Decimal("0"),
|
||||
help_text="TVA payée au fournisseur (achats nationaux uniquement).")
|
||||
"TVA déductible (€)", max_digits=12, decimal_places=2, default=Decimal("0"),
|
||||
help_text="Calculée automatiquement depuis le montant payé et le taux.")
|
||||
regime_tva = models.CharField(
|
||||
"Régime de TVA", max_length=12, choices=RegimeTva.choices, default=RegimeTva.NATIONALE)
|
||||
taux_tva = models.DecimalField(
|
||||
"Taux TVA autoliquidation (%)", max_digits=4, decimal_places=2, default=Decimal("0"),
|
||||
help_text="Taux français à auto-liquider pour les achats UE/import (ex. 20).")
|
||||
"Taux de TVA (%)", max_digits=4, decimal_places=2, default=Decimal("20"),
|
||||
choices=TAUX_TVA_CHOICES,
|
||||
help_text="Achat national : la TVA déductible est calculée. UE/import : taux auto-liquidé.")
|
||||
cree_le = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
@@ -261,6 +265,18 @@ class Depense(models.Model):
|
||||
def __str__(self):
|
||||
return f"{self.date} — {self.libelle}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# TVA déductible calculée : incluse dans le TTC (national), nulle en autoliq.
|
||||
t = self.taux_tva or Decimal("0")
|
||||
if self.autoliquidee:
|
||||
self.montant_tva = Decimal("0.00")
|
||||
elif t:
|
||||
self.montant_tva = ((self.montant_ttc or Decimal("0")) * t
|
||||
/ (Decimal("100") + t)).quantize(Decimal("0.01"))
|
||||
else:
|
||||
self.montant_tva = Decimal("0.00")
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def neutre(self):
|
||||
return bool(self.categorie and self.categorie.exclure_calculs)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if not lignes %}
|
||||
<form method="post" enctype="multipart/form-data" class="card">
|
||||
<form method="post" enctype="multipart/form-data" class="card" id="srcForm">
|
||||
{% csrf_token %}
|
||||
<div class="grid3">
|
||||
<div>
|
||||
@@ -59,8 +59,9 @@
|
||||
<input type="number" name="annee" value="{{ annee_defaut }}">
|
||||
</div>
|
||||
<div>
|
||||
<label>Capture d'écran (OCR)</label>
|
||||
<input type="file" name="image" accept="image/*">
|
||||
<label>Photo / capture (OCR) — fichier, appareil photo, ou <b>coller</b> (Ctrl/Cmd+V)</label>
|
||||
<input type="file" name="image" id="imgInput" accept="image/*" capture="environment">
|
||||
<div id="pasteInfo" class="sub" style="margin-top:4px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<label>…ou fichier CSV</label>
|
||||
@@ -110,5 +111,24 @@
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
window.addEventListener('paste', function(e){
|
||||
var input = document.getElementById('imgInput');
|
||||
if(!input || !e.clipboardData) return;
|
||||
for(var i=0; i<e.clipboardData.items.length; i++){
|
||||
var it = e.clipboardData.items[i];
|
||||
if(it.type && it.type.indexOf('image') === 0){
|
||||
var dt = new DataTransfer();
|
||||
dt.items.add(it.getAsFile());
|
||||
input.files = dt.files;
|
||||
var info = document.getElementById('pasteInfo');
|
||||
if(info){ info.textContent = 'Image collée — clique « Analyser ».'; info.style.color = '#34d399'; }
|
||||
e.preventDefault();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<body>
|
||||
<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>
|
||||
· <a href="/dashboard/">← Tableau de bord</a> · <a href="/import/">Importer un relevé</a></div>
|
||||
|
||||
{% if messages %}{% for m in messages %}<div class="msg {{ m.tags }}">{{ m }}</div>{% endfor %}{% endif %}
|
||||
|
||||
@@ -83,13 +83,12 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:22%">Libellé / vendeur</th>
|
||||
<th style="width:24%">Libellé / vendeur</th>
|
||||
<th style="width:16%">Catégorie</th>
|
||||
<th style="width:14%">Activité</th>
|
||||
<th style="width:15%">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:9%">Taux TVA</th>
|
||||
<th style="width:13%">Montant €</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -125,7 +124,10 @@
|
||||
</div>
|
||||
<div>
|
||||
<label>Taux TVA (%)</label>
|
||||
<input type="number" step="0.01" name="v_taux" value="20">
|
||||
<select name="v_taux">
|
||||
<option value="20">20 %</option><option value="10">10 %</option>
|
||||
<option value="5.5">5,5 %</option><option value="0">0 %</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Désignation</label>
|
||||
@@ -139,9 +141,8 @@
|
||||
</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 class="hint">Le montant TTC encaissé = le montant signé saisi plus haut.
|
||||
Une catégorie <b>neutre</b> n'enregistre pas de vente (mouvement de trésorerie).</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
@@ -169,9 +170,13 @@
|
||||
{% 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>
|
||||
<select name="l_taux">
|
||||
<option value="20">20 %</option><option value="10">10 %</option>
|
||||
<option value="5.5">5,5 %</option><option value="0">0 %</option>
|
||||
</select>
|
||||
</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>
|
||||
|
||||
+4
-10
@@ -19,13 +19,13 @@ CENT = Decimal("0.01")
|
||||
MOIS = {"janvier": 1, "février": 2, "fevrier": 2, "mars": 3, "avril": 4, "mai": 5,
|
||||
"juin": 6, "juillet": 7, "août": 8, "aout": 8, "septembre": 9,
|
||||
"octobre": 10, "novembre": 11, "décembre": 12, "decembre": 12}
|
||||
AMOUNT_RE = re.compile(r"^-?\d[\d .]*[.,]\d{2}$")
|
||||
AMOUNT_RE = re.compile(r"^-?\d[\d .]*[.,]\d{2}$")
|
||||
|
||||
|
||||
def _dec(v, d="0"):
|
||||
try:
|
||||
s = str(v or d)
|
||||
for ch in (" ", " ", " "):
|
||||
for ch in (" ", " ", " "):
|
||||
s = s.replace(ch, "")
|
||||
s = s.replace(",", ".").strip()
|
||||
return Decimal(s or d)
|
||||
@@ -224,16 +224,10 @@ def _creer(entreprise, dt, libelle, montant, taux, regime, categorie):
|
||||
prix_unitaire_ht=ht, taux_tva=taux)
|
||||
f.recompute_totaux()
|
||||
return "vente"
|
||||
abs_m = -montant
|
||||
if regime in (RegimeTva.INTRACOM, RegimeTva.IMPORT) or neutre:
|
||||
ttc, tva = abs_m, Decimal("0")
|
||||
else:
|
||||
ttc = abs_m
|
||||
tva = (abs_m * taux / (Decimal("100") + taux)).quantize(CENT) if taux else Decimal("0")
|
||||
# montant_tva est calculé automatiquement dans Depense.save() depuis le taux.
|
||||
Depense.objects.create(entreprise=entreprise, date=dt, libelle=libelle,
|
||||
categorie=categorie, regime_tva=regime,
|
||||
taux_tva=taux if regime != RegimeTva.NATIONALE else Decimal("0"),
|
||||
montant_ttc=ttc, montant_tva=tva)
|
||||
taux_tva=taux, montant_ttc=-montant)
|
||||
return "depense"
|
||||
|
||||
|
||||
|
||||
@@ -117,7 +117,6 @@ def saisie_paiement(request):
|
||||
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)):
|
||||
@@ -132,7 +131,6 @@ def saisie_paiement(request):
|
||||
"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"))
|
||||
@@ -148,9 +146,10 @@ def saisie_paiement(request):
|
||||
paiement = Paiement.objects.create(
|
||||
entreprise=entreprise, date=d, libelle=libelle, montant_total=total_abs, sens="debit")
|
||||
for l in lignes:
|
||||
# montant_tva est calculé automatiquement dans Depense.save() depuis le taux.
|
||||
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"])
|
||||
taux_tva=l["taux"], montant_ttc=l["montant"])
|
||||
messages.success(request, f"Opération « {libelle} » enregistrée ({len(lignes)} dépense(s)).")
|
||||
return redirect("saisie_paiement")
|
||||
|
||||
Reference in New Issue
Block a user