from django.contrib import admin from django.utils import timezone from .models import ( Bareme, Entreprise, Client, Facture, LigneFacture, Depense, Paiement, Categorie, ) class ScopedAdmin(admin.ModelAdmin): """Cloisonne les données par entreprise pour les non-superadmins.""" scope_path = "entreprise" def get_queryset(self, request): qs = super().get_queryset(request) if request.user.is_superuser: return qs return qs.filter(**{f"{self.scope_path}__in": Entreprise.accessibles(request.user)}) def formfield_for_foreignkey(self, db_field, request, **kwargs): if not request.user.is_superuser: acc = Entreprise.accessibles(request.user) if db_field.name == "entreprise": kwargs["queryset"] = acc elif db_field.name == "client": kwargs["queryset"] = Client.objects.filter(entreprise__in=acc) elif db_field.name == "paiement": kwargs["queryset"] = Paiement.objects.filter(entreprise__in=acc) 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") list_filter = ("usage", "exclure_calculs", "actif") list_editable = ("usage", "exclure_calculs", "actif", "ordre") search_fields = ("nom",) @admin.register(Bareme) class BaremeAdmin(admin.ModelAdmin): list_display = ("annee", "activite", "taux_urssaf", "abattement_fiscal", "taux_vl", "seuil_ca", "seuil_tva_base") list_filter = ("annee", "activite") # ----- Entreprise (accès) ----- @admin.register(Entreprise) class EntrepriseAdmin(admin.ModelAdmin): list_display = ("nom", "activite", "franchise_tva", "versement_liberatoire", "num_tva_intracom", "vue_tva", "email") list_filter = ("activite", "franchise_tva", "versement_liberatoire") search_fields = ("nom", "siret", "num_tva_intracom") filter_horizontal = ("utilisateurs", "groupes") def get_queryset(self, request): qs = super().get_queryset(request) if request.user.is_superuser: return qs 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") list_filter = ("entreprise",) search_fields = ("nom", "email", "siret") class LigneFactureInline(admin.TabularInline): model = LigneFacture extra = 1 @admin.action(description="Marquer comme encaissée (aujourd'hui)") def marquer_encaissee(modeladmin, request, queryset): queryset.update(statut="encaissee", date_encaissement=timezone.now().date()) @admin.register(Facture) class FactureAdmin(ScopedAdmin): list_display = ("numero", "entreprise", "client", "date_emission", "date_encaissement", "statut", "montant_ht", "montant_tva", "montant_ttc") list_filter = ("entreprise", "statut", "activite", "date_emission") search_fields = ("numero", "client__nom") date_hierarchy = "date_emission" inlines = [LigneFactureInline] actions = [marquer_encaissee] readonly_fields = ("montant_ht", "montant_tva", "montant_ttc") def save_related(self, request, form, formsets, change): super().save_related(request, form, formsets, change) form.instance.recompute_totaux() class DepenseInline(admin.TabularInline): model = Depense extra = 0 fields = ("date", "libelle", "categorie", "activite", "regime_tva", "taux_tva", "montant_ttc", "montant_tva") @admin.register(Paiement) class PaiementAdmin(ScopedAdmin): list_display = ("date", "entreprise", "libelle", "sens", "montant_total", "reparti", "reste", "equilibre") list_filter = ("entreprise", "sens", "date") search_fields = ("libelle",) date_hierarchy = "date" inlines = [DepenseInline] @admin.display(description="Réparti") def reparti(self, obj): return obj.reparti @admin.display(description="Reste") def reste(self, obj): return obj.reste @admin.display(boolean=True, description="Équilibré") def equilibre(self, obj): return obj.equilibre @admin.register(Depense) class DepenseAdmin(ScopedAdmin): list_display = ("date", "entreprise", "libelle", "categorie", "activite", "regime_tva", "montant_ttc", "montant_tva", "tva_autoliq", "paiement") list_filter = ("entreprise", "categorie", "regime_tva", "activite", "date") search_fields = ("libelle",) date_hierarchy = "date" @admin.display(description="TVA auto-liquidée") def tva_autoliq(self, obj): return obj.tva_autoliquidee