""" PX Action Center admin """ from django.contrib import admin from django.utils.html import format_html, mark_safe from .models import PXAction, PXActionAttachment, PXActionLog, PXActionSLAConfig, RoutingRule class PXActionLogInline(admin.TabularInline): """Inline admin for action logs""" model = PXActionLog extra = 1 fields = ["log_type", "message", "created_by", "created_at"] readonly_fields = ["created_at"] ordering = ["-created_at"] class PXActionAttachmentInline(admin.TabularInline): """Inline admin for action attachments""" model = PXActionAttachment extra = 0 fields = ["file", "filename", "is_evidence", "uploaded_by", "description"] readonly_fields = ["file_size"] @admin.register(PXAction) class PXActionAdmin(admin.ModelAdmin): """PX Action admin""" list_display = [ "title_preview", "source_type", "hospital", "category", "severity_badge", "status_badge", "sla_indicator", "assigned_to", "escalation_level", "created_at", ] list_filter = [ "status", "source_type", "severity", "priority", "category", "is_overdue", "requires_approval", "hospital", "created_at", ] search_fields = ["title", "description", "metadata"] ordering = ["-created_at"] date_hierarchy = "created_at" inlines = [PXActionLogInline, PXActionAttachmentInline] fieldsets = ( ("Source", {"fields": ("source_type", "content_type", "object_id")}), ("Action Details", {"fields": ("title", "description", "category")}), ("Organization", {"fields": ("hospital", "department")}), ("Classification", {"fields": ("priority", "severity")}), ("Status & Assignment", {"fields": ("status", "assigned_to", "assigned_at")}), ("SLA Tracking", {"fields": ("due_at", "is_overdue", "reminder_sent_at", "escalated_at", "escalation_level")}), ("Approval", {"fields": ("requires_approval", "approved_by", "approved_at")}), ("Closure", {"fields": ("closed_at", "closed_by")}), ("Action Plan & Outcome", {"fields": ("action_plan", "outcome"), "classes": ("collapse",)}), ("Metadata", {"fields": ("metadata", "created_at", "updated_at"), "classes": ("collapse",)}), ) readonly_fields = [ "assigned_at", "reminder_sent_at", "escalated_at", "approved_at", "closed_at", "created_at", "updated_at", ] def get_queryset(self, request): qs = super().get_queryset(request) return qs.select_related("hospital", "department", "assigned_to", "approved_by", "closed_by", "content_type") def title_preview(self, obj): """Show preview of title""" return obj.title[:60] + "..." if len(obj.title) > 60 else obj.title title_preview.short_description = "Title" def severity_badge(self, obj): """Display severity with color badge""" colors = { "low": "info", "medium": "warning", "high": "danger", "critical": "danger", } color = colors.get(obj.severity, "secondary") return format_html('{}', color, obj.get_severity_display()) severity_badge.short_description = "Severity" def status_badge(self, obj): """Display status with color badge""" colors = { "open": "danger", "in_progress": "warning", "pending_approval": "info", "approved": "success", "closed": "success", "cancelled": "secondary", } color = colors.get(obj.status, "secondary") return format_html('{}', color, obj.get_status_display()) status_badge.short_description = "Status" def sla_indicator(self, obj): """Display SLA status""" if obj.is_overdue: return format_html('OVERDUE (Level {})', obj.escalation_level) from django.utils import timezone time_remaining = obj.due_at - timezone.now() hours_remaining = time_remaining.total_seconds() / 3600 if hours_remaining < 4: return mark_safe('DUE SOON') else: return mark_safe('ON TIME') sla_indicator.short_description = "SLA" @admin.register(PXActionLog) class PXActionLogAdmin(admin.ModelAdmin): """PX Action log admin""" list_display = ["action", "log_type", "message_preview", "created_by", "created_at"] list_filter = ["log_type", "created_at"] search_fields = ["message", "action__title"] ordering = ["-created_at"] fieldsets = ( (None, {"fields": ("action", "log_type", "message")}), ("Status Change", {"fields": ("old_status", "new_status"), "classes": ("collapse",)}), ("Details", {"fields": ("created_by", "metadata")}), ("Metadata", {"fields": ("created_at", "updated_at")}), ) readonly_fields = ["created_at", "updated_at"] def get_queryset(self, request): qs = super().get_queryset(request) return qs.select_related("action", "created_by") def message_preview(self, obj): """Show preview of message""" return obj.message[:100] + "..." if len(obj.message) > 100 else obj.message message_preview.short_description = "Message" @admin.register(PXActionAttachment) class PXActionAttachmentAdmin(admin.ModelAdmin): """PX Action attachment admin""" list_display = ["action", "filename", "is_evidence", "file_size", "uploaded_by", "created_at"] list_filter = ["is_evidence", "file_type", "created_at"] search_fields = ["filename", "description", "action__title"] ordering = ["-created_at"] fieldsets = ( (None, {"fields": ("action", "file", "filename", "file_type", "file_size")}), ("Details", {"fields": ("is_evidence", "uploaded_by", "description")}), ("Metadata", {"fields": ("created_at", "updated_at")}), ) readonly_fields = ["file_size", "created_at", "updated_at"] def get_queryset(self, request): qs = super().get_queryset(request) return qs.select_related("action", "uploaded_by") @admin.register(PXActionSLAConfig) class PXActionSLAConfigAdmin(admin.ModelAdmin): """PX Action SLA configuration admin""" list_display = [ "name", "hospital", "department", "critical_hours", "high_hours", "medium_hours", "low_hours", "auto_escalate", "is_active", ] list_filter = ["is_active", "auto_escalate", "hospital"] search_fields = ["name"] ordering = ["hospital", "name"] fieldsets = ( (None, {"fields": ("name", "hospital", "department")}), ("SLA Durations (hours)", {"fields": ("critical_hours", "high_hours", "medium_hours", "low_hours")}), ("Reminder Configuration", {"fields": ("reminder_hours_before",)}), ("Escalation Configuration", {"fields": ("auto_escalate", "escalation_delay_hours")}), ("Status", {"fields": ("is_active",)}), ("Metadata", {"fields": ("created_at", "updated_at")}), ) readonly_fields = ["created_at", "updated_at"] def get_queryset(self, request): qs = super().get_queryset(request) return qs.select_related("hospital", "department") @admin.register(RoutingRule) class RoutingRuleAdmin(admin.ModelAdmin): """Routing rule admin""" list_display = [ "name", "source_type", "category", "severity", "hospital", "assign_to_role", "priority", "is_active", ] list_filter = ["source_type", "severity", "is_active", "hospital"] search_fields = ["name", "description"] ordering = ["-priority", "name"] fieldsets = ( (None, {"fields": ("name", "description", "priority")}), ("Conditions", {"fields": ("source_type", "category", "severity", "hospital", "department")}), ("Routing Target", {"fields": ("assign_to_role", "assign_to_user", "assign_to_department")}), ("Status", {"fields": ("is_active",)}), ("Metadata", {"fields": ("created_at", "updated_at")}), ) readonly_fields = ["created_at", "updated_at"] def get_queryset(self, request): qs = super().get_queryset(request) return qs.select_related("hospital", "department", "assign_to_user", "assign_to_department")