""" Notifications admin """ from django.contrib import admin from django.utils.html import format_html from .models import NotificationLog, NotificationTemplate, UserNotification from .settings_models import HospitalNotificationSettings, NotificationSettingsLog @admin.register(NotificationLog) class NotificationLogAdmin(admin.ModelAdmin): """Notification log admin""" list_display = [ "channel", "recipient", "subject_preview", "status_badge", "provider", "retry_count", "sent_at", "created_at", ] list_filter = ["channel", "status", "provider", "created_at", "sent_at"] search_fields = ["recipient", "subject", "message", "provider_message_id"] ordering = ["-created_at"] date_hierarchy = "created_at" fieldsets = ( ("Delivery", {"fields": ("channel", "recipient", "subject", "message")}), ("Status", {"fields": ("status", "sent_at", "delivered_at", "error", "retry_count")}), ("Provider", {"fields": ("provider", "provider_message_id", "provider_response"), "classes": ("collapse",)}), ("Related Object", {"fields": ("content_type", "object_id"), "classes": ("collapse",)}), ("Metadata", {"fields": ("metadata", "created_at", "updated_at"), "classes": ("collapse",)}), ) readonly_fields = [ "sent_at", "delivered_at", "provider_message_id", "provider_response", "created_at", "updated_at", ] def has_add_permission(self, request): # Notifications should only be created programmatically return False def has_delete_permission(self, request, obj=None): # Keep notification logs for compliance return False def subject_preview(self, obj): """Show preview of subject""" if obj.subject: return obj.subject[:50] + "..." if len(obj.subject) > 50 else obj.subject return "-" subject_preview.short_description = "Subject" def status_badge(self, obj): """Display status with color badge""" colors = { "pending": "warning", "sending": "info", "sent": "success", "delivered": "success", "failed": "danger", "bounced": "danger", } color = colors.get(obj.status, "secondary") return format_html('{}', color, obj.get_status_display()) status_badge.short_description = "Status" @admin.register(NotificationTemplate) class NotificationTemplateAdmin(admin.ModelAdmin): """Notification template admin""" list_display = ["name", "template_type", "is_active", "created_at"] list_filter = ["template_type", "is_active"] search_fields = ["name", "description"] ordering = ["name"] fieldsets = ( (None, {"fields": ("name", "template_type", "description")}), ("SMS Templates", {"fields": ("sms_template", "sms_template_ar"), "classes": ("collapse",)}), ("WhatsApp Templates", {"fields": ("whatsapp_template", "whatsapp_template_ar"), "classes": ("collapse",)}), ( "Email Templates", { "fields": ("email_subject", "email_subject_ar", "email_template", "email_template_ar"), "classes": ("collapse",), }, ), ("Status", {"fields": ("is_active",)}), ("Metadata", {"fields": ("created_at", "updated_at")}), ) readonly_fields = ["created_at", "updated_at"] @admin.register(HospitalNotificationSettings) class HospitalNotificationSettingsAdmin(admin.ModelAdmin): """Hospital notification settings admin""" list_display = ["hospital", "notifications_enabled", "updated_at"] list_filter = ["notifications_enabled", "updated_at"] search_fields = ["hospital__name"] fieldsets = ( ("Hospital", {"fields": ("hospital",)}), ("Master Control", {"fields": ("notifications_enabled",)}), ( "Complaint Notifications", { "fields": ( "complaint_acknowledgment_email", "complaint_acknowledgment_sms", "complaint_acknowledgment_whatsapp", "complaint_assigned_email", "complaint_assigned_sms", "complaint_assigned_whatsapp", "complaint_status_changed_email", "complaint_status_changed_sms", "complaint_status_changed_whatsapp", "complaint_resolved_email", "complaint_resolved_sms", "complaint_resolved_whatsapp", "complaint_closed_email", "complaint_closed_sms", "complaint_closed_whatsapp", ), "classes": ("collapse",), }, ), ( "Explanation Notifications", { "fields": ( "explanation_requested_email", "explanation_requested_sms", "explanation_requested_whatsapp", "explanation_reminder_email", "explanation_reminder_sms", "explanation_reminder_whatsapp", "explanation_overdue_email", "explanation_overdue_sms", "explanation_overdue_whatsapp", "explanation_received_email", "explanation_received_sms", "explanation_received_whatsapp", "explanation_manager_cc", ), "classes": ("collapse",), }, ), ( "Survey Notifications", { "fields": ( "survey_invitation_email", "survey_invitation_sms", "survey_invitation_whatsapp", "survey_reminder_email", "survey_reminder_sms", "survey_reminder_whatsapp", "survey_completed_email", "survey_completed_sms", ), "classes": ("collapse",), }, ), ( "Action Notifications", { "fields": ( "action_assigned_email", "action_assigned_sms", "action_assigned_whatsapp", "action_due_soon_email", "action_due_soon_sms", "action_overdue_email", "action_overdue_sms", ), "classes": ("collapse",), }, ), ( "SLA Notifications", { "fields": ( "sla_reminder_email", "sla_reminder_sms", "sla_breach_email", "sla_breach_sms", "sla_breach_whatsapp", ), "classes": ("collapse",), }, ), ( "Onboarding Notifications", { "fields": ( "onboarding_invitation_email", "onboarding_invitation_sms", "onboarding_invitation_whatsapp", "onboarding_reminder_email", "onboarding_reminder_sms", "onboarding_reminder_whatsapp", "onboarding_completion_email", "onboarding_completion_sms", ), "classes": ("collapse",), }, ), ( "Quiet Hours", { "fields": ("quiet_hours_enabled", "quiet_hours_start", "quiet_hours_end"), }, ), ( "Retry Settings", { "fields": ("retry_failed_notifications", "max_retries"), }, ), ) readonly_fields = ["created_at", "updated_at"] @admin.register(NotificationSettingsLog) class NotificationSettingsLogAdmin(admin.ModelAdmin): """Notification settings change log admin""" list_display = ["hospital", "field_name", "old_value", "new_value", "changed_by", "created_at"] list_filter = ["hospital", "created_at"] search_fields = ["field_name", "changed_by__email", "changed_by__first_name", "changed_by__last_name"] ordering = ["-created_at"] readonly_fields = ["hospital", "changed_by", "field_name", "old_value", "new_value", "created_at"] def has_add_permission(self, request): return False def has_change_permission(self, request, obj=None): return False def has_delete_permission(self, request, obj=None): return False @admin.register(UserNotification) class UserNotificationAdmin(admin.ModelAdmin): """User notification admin""" list_display = ["user", "notification_type", "title_preview", "is_read", "is_dismissed", "created_at"] list_filter = ["notification_type", "is_read", "is_dismissed", "created_at"] search_fields = ["user__email", "title", "message"] ordering = ["-created_at"] date_hierarchy = "created_at" fieldsets = ( ("User", {"fields": ("user",)}), ("Content", {"fields": ("title", "title_ar", "message", "message_ar")}), ("Type & Status", {"fields": ("notification_type", "is_read", "read_at", "is_dismissed", "dismissed_at")}), ("Links", {"fields": ("action_url", "email_log"), "classes": ("collapse",)}), ("Related Object", {"fields": ("content_type", "object_id"), "classes": ("collapse",)}), ("Timestamps", {"fields": ("created_at", "updated_at"), "classes": ("collapse",)}), ) readonly_fields = ["created_at", "updated_at", "read_at", "dismissed_at"] def title_preview(self, obj): """Short title preview""" return obj.title[:50] + "..." if len(obj.title) > 50 else obj.title title_preview.short_description = "Title" actions = ["mark_as_read", "mark_as_dismissed"] def mark_as_read(self, request, queryset): """Mark selected notifications as read""" for notification in queryset: notification.mark_as_read() self.message_user(request, f"{queryset.count()} notifications marked as read") mark_as_read.short_description = "Mark selected as read" def mark_as_dismissed(self, request, queryset): """Mark selected notifications as dismissed""" for notification in queryset: notification.mark_as_dismissed() self.message_user(request, f"{queryset.count()} notifications dismissed") mark_as_dismissed.short_description = "Dismiss selected"