Multi-utilisateur : droits par entreprise + renommage Operation bancaire
This commit is contained in:
+33
-17
@@ -3,8 +3,9 @@ Modèles de données — JB Compta.
|
||||
"""
|
||||
from decimal import Decimal
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.db.models import Sum
|
||||
from django.db.models import Sum, Q
|
||||
|
||||
|
||||
class Activite(models.TextChoices):
|
||||
@@ -27,7 +28,7 @@ class RegimeTva(models.TextChoices):
|
||||
|
||||
|
||||
class Categorie(models.Model):
|
||||
"""Catégorie globale. exclure_calculs=True => mouvement neutre (hors fiscal)."""
|
||||
"""Catégorie globale (mutualisée). exclure_calculs=True => mouvement neutre."""
|
||||
USAGE = [("depense", "Dépense"), ("vente", "Vente"), ("neutre", "Mouvement neutre")]
|
||||
nom = models.CharField(max_length=100, unique=True)
|
||||
usage = models.CharField(max_length=10, choices=USAGE, default="depense")
|
||||
@@ -48,6 +49,7 @@ class Categorie(models.Model):
|
||||
|
||||
|
||||
class Bareme(models.Model):
|
||||
"""Barème mutualisé (partagé entre toutes les entreprises)."""
|
||||
activite = models.CharField(max_length=20, choices=Activite.choices)
|
||||
annee = models.PositiveIntegerField()
|
||||
taux_urssaf = models.DecimalField("Taux cotisations URSSAF (%)", max_digits=5, decimal_places=2)
|
||||
@@ -73,18 +75,24 @@ class Entreprise(models.Model):
|
||||
siret = models.CharField(max_length=20, blank=True)
|
||||
activite = models.CharField(
|
||||
"Activité principale", max_length=20, choices=Activite.choices,
|
||||
default=Activite.SERVICE_BNC,
|
||||
help_text="Activité par défaut des nouvelles factures.")
|
||||
default=Activite.SERVICE_BNC, help_text="Activité par défaut des nouvelles factures.")
|
||||
franchise_tva = models.BooleanField(
|
||||
"En franchise de TVA", default=False,
|
||||
help_text="Décochez si vous facturez et déclarez la TVA.")
|
||||
"En franchise de TVA", default=False, help_text="Décochez si vous facturez la TVA.")
|
||||
taux_tva_defaut = models.DecimalField(
|
||||
"Taux de TVA par défaut (%)", max_digits=4, decimal_places=2, default=Decimal("20.00"))
|
||||
versement_liberatoire = models.BooleanField("Option versement libératoire", default=False)
|
||||
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")
|
||||
"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",
|
||||
help_text="Utilisateurs ayant accès directement à cette entreprise.")
|
||||
groupes = models.ManyToManyField(
|
||||
"auth.Group", blank=True, related_name="entreprises",
|
||||
verbose_name="Groupes autorisés",
|
||||
help_text="Tous les membres de ces groupes ont accès à cette entreprise.")
|
||||
email = models.EmailField(blank=True)
|
||||
adresse = models.TextField(blank=True)
|
||||
cree_le = models.DateTimeField(auto_now_add=True)
|
||||
@@ -100,6 +108,16 @@ class Entreprise(models.Model):
|
||||
def bareme(self, annee):
|
||||
return Bareme.objects.filter(activite=self.activite, annee=annee).first()
|
||||
|
||||
@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:
|
||||
return cls.objects.all()
|
||||
return cls.objects.filter(
|
||||
Q(utilisateurs=user) | Q(groupes__in=user.groups.all())).distinct()
|
||||
|
||||
|
||||
class Client(models.Model):
|
||||
entreprise = models.ForeignKey(Entreprise, on_delete=models.CASCADE, related_name="clients")
|
||||
@@ -125,8 +143,7 @@ class Facture(models.Model):
|
||||
activite = models.CharField(max_length=20, choices=Activite.choices)
|
||||
date_emission = models.DateField()
|
||||
date_encaissement = models.DateField(
|
||||
null=True, blank=True,
|
||||
help_text="Le CA micro est compté à l'encaissement.")
|
||||
null=True, blank=True, help_text="Le CA micro est compté à l'encaissement.")
|
||||
statut = models.CharField(max_length=12, choices=StatutFacture.choices, default=StatutFacture.BROUILLON)
|
||||
montant_ht = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal("0"))
|
||||
montant_tva = models.DecimalField(max_digits=12, decimal_places=2, default=Decimal("0"))
|
||||
@@ -184,15 +201,14 @@ class Paiement(models.Model):
|
||||
libelle = models.CharField("Libellé bancaire", max_length=255)
|
||||
montant_total = models.DecimalField(max_digits=12, decimal_places=2)
|
||||
sens = models.CharField(max_length=6, choices=SENS, default="debit")
|
||||
categorie = models.ForeignKey(Categorie, on_delete=models.SET_NULL,
|
||||
null=True, blank=True, related_name="paiements",
|
||||
help_text="Surtout pour les mouvements neutres "
|
||||
"(remboursement TVA, virement…).")
|
||||
categorie = models.ForeignKey(Categorie, on_delete=models.SET_NULL, null=True, blank=True,
|
||||
related_name="paiements",
|
||||
help_text="Surtout pour les mouvements neutres.")
|
||||
cree_le = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Paiement"
|
||||
verbose_name_plural = "Paiements"
|
||||
verbose_name = "Opération bancaire"
|
||||
verbose_name_plural = "Opérations bancaires"
|
||||
ordering = ["-date"]
|
||||
|
||||
def __str__(self):
|
||||
@@ -215,7 +231,7 @@ class Paiement(models.Model):
|
||||
class Depense(models.Model):
|
||||
entreprise = models.ForeignKey(Entreprise, on_delete=models.CASCADE, related_name="depenses")
|
||||
paiement = models.ForeignKey(Paiement, on_delete=models.SET_NULL, null=True, blank=True,
|
||||
related_name="depenses",
|
||||
related_name="depenses", verbose_name="Opération bancaire",
|
||||
help_text="Opération bancaire dont cette dépense fait partie.")
|
||||
date = models.DateField()
|
||||
activite = models.CharField(
|
||||
|
||||
Reference in New Issue
Block a user