from django.contrib import admin from .models import ( Team, Notification, NotificationAttachment, NotificationRecipient, TeamNotificationTarget, TeamNotificationRead, Discussion, Message, MessageAttachment, NotificationRule, ) class NotificationRecipientInline(admin.TabularInline): model = NotificationRecipient extra = 0 readonly_fields = ['read_at', 'archived_at'] class TeamNotificationTargetInline(admin.TabularInline): model = TeamNotificationTarget extra = 0 class NotificationAttachmentInline(admin.TabularInline): model = NotificationAttachment extra = 0 readonly_fields = ['uploaded_at', 'name'] @admin.register(Team) class TeamAdmin(admin.ModelAdmin): list_display = ['name', 'member_count', 'created_by', 'created_at'] search_fields = ['name', 'description'] filter_horizontal = ['members'] def member_count(self, obj): return obj.members.count() member_count.short_description = 'Membres' @admin.register(Notification) class NotificationAdmin(admin.ModelAdmin): list_display = [ 'title', 'notification_type', 'sender', 'created_at', 'expires_at', 'is_system', 'source_app', ] list_filter = ['notification_type', 'is_system', 'source_app', 'created_at'] search_fields = ['title', 'content'] readonly_fields = ['created_at'] inlines = [NotificationAttachmentInline, NotificationRecipientInline, TeamNotificationTargetInline] date_hierarchy = 'created_at' @admin.register(NotificationAttachment) class NotificationAttachmentAdmin(admin.ModelAdmin): list_display = ['name', 'notification', 'uploaded_by', 'uploaded_at', 'is_image'] search_fields = ['name', 'notification__title'] readonly_fields = ['uploaded_at', 'is_image'] @admin.register(NotificationRecipient) class NotificationRecipientAdmin(admin.ModelAdmin): list_display = ['notification', 'user', 'read_at', 'archived_at'] list_filter = ['read_at', 'archived_at'] search_fields = ['user__username', 'notification__title'] readonly_fields = ['read_at', 'archived_at'] @admin.register(TeamNotificationTarget) class TeamNotificationTargetAdmin(admin.ModelAdmin): list_display = ['notification', 'team'] search_fields = ['team__name', 'notification__title'] @admin.register(TeamNotificationRead) class TeamNotificationReadAdmin(admin.ModelAdmin): list_display = ['team_notification', 'user', 'read_at'] search_fields = ['user__username'] readonly_fields = ['read_at'] # ───────────────────────────────────────────────────────────────────────────── # Règles de notification # ───────────────────────────────────────────────────────────────────────────── @admin.register(NotificationRule) class NotificationRuleAdmin(admin.ModelAdmin): list_display = [ 'name', 'is_active', 'trigger_event', 'trigger_cancellation_type', 'notification_type', 'team_list', 'updated_at', ] list_filter = ['is_active', 'trigger_event', 'trigger_cancellation_type', 'notification_type'] search_fields = ['name', 'title_template', 'content_template'] filter_horizontal = ['recipient_teams', 'recipient_users'] readonly_fields = ['created_at', 'updated_at'] fieldsets = [ (None, { 'fields': ['name', 'is_active'], }), ('Déclencheur', { 'fields': ['trigger_event', 'trigger_cancellation_type'], 'description': ( 'Sélectionnez l\'événement qui déclenche cette règle. ' 'Utilisez le filtre « Type d\'annulation » pour ne cibler qu\'un cas précis.' ), }), ('Contenu de la notification', { 'fields': ['notification_type', 'single_claim', 'title_template', 'content_template'], 'description': ( 'Variables disponibles dans les modèles : ' '{intervention_code}, {intervention_title}, ' '{cancellation_type_label}, {cancellation_reason}' ), }), ('Destinataires', { 'fields': ['recipient_teams', 'recipient_users'], }), ('Informations système', { 'fields': ['created_at', 'updated_at'], 'classes': ['collapse'], }), ] def team_list(self, obj): teams = obj.recipient_teams.select_related('company').values_list('name', 'company__name') return ', '.join(f"{n} ({c})" for n, c in teams) or '—' team_list.short_description = 'Équipes' # ───────────────────────────────────────────────────────────────────────────── # Discussion / Messaging # ───────────────────────────────────────────────────────────────────────────── class MessageInline(admin.TabularInline): model = Message extra = 0 readonly_fields = ['created_at', 'author'] fields = ['author', 'content', 'created_at', 'is_deleted'] @admin.register(Discussion) class DiscussionAdmin(admin.ModelAdmin): list_display = ['title', 'created_by', 'created_at', 'updated_at', 'is_closed', 'object_label', 'message_count'] list_filter = ['is_closed', 'created_at'] search_fields = ['title', 'object_label', 'created_by__username'] readonly_fields = ['created_at', 'updated_at', 'content_type', 'object_id', 'object_url', 'object_label'] filter_horizontal = ['participants'] inlines = [MessageInline] def message_count(self, obj): return obj.messages.filter(is_deleted=False).count() message_count.short_description = 'Messages' class MessageAttachmentInline(admin.TabularInline): model = MessageAttachment extra = 0 readonly_fields = ['uploaded_at', 'name', 'is_image'] @admin.register(Message) class MessageAdmin(admin.ModelAdmin): list_display = ['author', 'discussion', 'created_at', 'is_deleted'] list_filter = ['is_deleted', 'created_at'] search_fields = ['author__username', 'content', 'discussion__title'] readonly_fields = ['created_at'] inlines = [MessageAttachmentInline]