164 lines
6.5 KiB
Python
164 lines
6.5 KiB
Python
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]
|