from django import forms from django.contrib import admin from django.contrib.contenttypes.models import ContentType from django.db import models as db_models from .models import ( DocumentAccessLink, DocumentAttachment, DocumentFolder, DocumentFolderAccessLink, DocumentFolderAttachment, DocumentFolderShare, DocumentShare, DocumentTag, DocumentType, DocumentValidation, DocumentVersion, ManagedDocument, ) @admin.register(DocumentFolder) class DocumentFolderAdmin(admin.ModelAdmin): list_display = ("name", "application_label", "is_predefined", "created_by") list_filter = ("is_predefined", "application_label", "thematics") search_fields = ("name", "application_label") filter_horizontal = ("parent_folders", "thematics") @admin.register(DocumentType) class DocumentTypeAdmin(admin.ModelAdmin): list_display = ("code", "label") search_fields = ("code", "label") class DocumentTagForm(forms.ModelForm): """Limit related_content_types choices to asset models + Project + Intervention.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) allowed = ContentType.objects.filter( db_models.Q(app_label='assets') | db_models.Q(app_label='projects', model='project') | db_models.Q(app_label='interventions', model='intervention') ).order_by('app_label', 'model') self.fields['related_content_types'].queryset = allowed class Meta: model = DocumentTag fields = '__all__' @admin.register(DocumentTag) class DocumentTagAdmin(admin.ModelAdmin): form = DocumentTagForm list_display = ("name", "slug", "order", "is_unique", "show_in_asset_detail", "display_thematics", "display_related_models") list_filter = ("is_unique", "show_in_asset_detail", "thematics") search_fields = ("name_fr", "slug") filter_horizontal = ("thematics", "related_content_types") fieldsets = ( (None, { "fields": ("name_fr", "name_nl", "slug", "order", "is_unique", "show_in_asset_detail"), }), ("Filtrage", { "fields": ("thematics", "related_content_types"), }), ("Paramètres supplémentaires", { "fields": ("extra_params_schema",), "description": ( "Définit les champs supplémentaires affichés dans la modale d'upload quand ce tag est sélectionné. " "Format JSON : liste d'objets avec les clés key, label_fr, " "label_nl, type (text / number / " "textarea / select), required (bool), " "placeholder_fr, placeholder_nl. " "Pour select : ajouter options (liste d'objets " "{\"value\", \"label_fr\", \"label_nl\"})." ), }), ) def display_thematics(self, obj): return ", ".join([t.name for t in obj.thematics.all()]) display_thematics.short_description = "Thématiques" def display_related_models(self, obj): cts = obj.related_content_types.all() if not cts: return "— (tous)" return ", ".join([f"{ct.app_label}.{ct.model}" for ct in cts]) display_related_models.short_description = "Modèles liés" class DocumentVersionInline(admin.TabularInline): model = DocumentVersion fk_name = "document" extra = 0 readonly_fields = ("version_number", "uploaded_by", "upload_date") @admin.register(ManagedDocument) class ManagedDocumentAdmin(admin.ModelAdmin): list_display = ("title", "created_by", "updated_at", "is_archived") list_filter = ("is_archived", "types", "tags") search_fields = ("title", "description") inlines = [DocumentVersionInline] @admin.register(DocumentVersion) class DocumentVersionAdmin(admin.ModelAdmin): list_display = ("document", "version_number", "uploaded_by", "upload_date", "status") list_filter = ("status",) search_fields = ("document__title", "comment") @admin.register(DocumentValidation) class DocumentValidationAdmin(admin.ModelAdmin): list_display = ("version", "role", "status", "validated_by", "validated_at") list_filter = ("status", "role") @admin.register(DocumentShare) class DocumentShareAdmin(admin.ModelAdmin): list_display = ("document", "user", "permission", "created_at") list_filter = ("permission",) @admin.register(DocumentFolderShare) class DocumentFolderShareAdmin(admin.ModelAdmin): list_display = ("folder", "user", "permission", "created_at") list_filter = ("permission",) @admin.register(DocumentFolderAccessLink) class DocumentFolderAccessLinkAdmin(admin.ModelAdmin): list_display = ("folder", "permission", "expires_at", "created_at") list_filter = ("permission",) search_fields = ("token",) @admin.register(DocumentAccessLink) class DocumentAccessLinkAdmin(admin.ModelAdmin): list_display = ("document", "permission", "expires_at", "created_at") list_filter = ("permission",) search_fields = ("token",) @admin.register(DocumentAttachment) class DocumentAttachmentAdmin(admin.ModelAdmin): list_display = ("document", "content_type", "object_id", "attached_at") list_filter = ("content_type",) search_fields = ("document__title",) @admin.register(DocumentFolderAttachment) class DocumentFolderAttachmentAdmin(admin.ModelAdmin): """Admin générique pour voir tous les liens dossier-objet.""" list_display = ("folder", "content_type", "object_id", "get_object_display", "is_default", "attached_at") list_filter = ("is_default", "content_type", "folder") search_fields = ("folder__name",) autocomplete_fields = ['folder'] readonly_fields = ('get_object_display',) def get_object_display(self, obj): """Affiche l'objet lié.""" if obj.content_object: return str(obj.content_object) return f"ID {obj.object_id} (supprimé)" get_object_display.short_description = "Objet lié"