""" Admin configuration for Insurance Approvals app. """ from django.contrib import admin from django.utils.html import format_html from django.urls import reverse from django.utils import timezone from .models import ( InsuranceApprovalRequest, ApprovalDocument, ApprovalStatusHistory, ApprovalCommunicationLog, ApprovalTemplate ) class ApprovalDocumentInline(admin.TabularInline): model = ApprovalDocument extra = 0 fields = ('document_type', 'title', 'file', 'file_size_mb', 'uploaded_at', 'uploaded_by') readonly_fields = ('file_size_mb', 'uploaded_at', 'uploaded_by') def file_size_mb(self, obj): if obj.file_size: return f"{obj.file_size_mb} MB" return "-" file_size_mb.short_description = 'File Size' class ApprovalStatusHistoryInline(admin.TabularInline): model = ApprovalStatusHistory extra = 0 fields = ('from_status', 'to_status', 'reason', 'changed_at', 'changed_by') readonly_fields = ('changed_at', 'changed_by') can_delete = False class ApprovalCommunicationLogInline(admin.TabularInline): model = ApprovalCommunicationLog extra = 0 fields = ('communication_type', 'subject', 'contact_person', 'communicated_at', 'follow_up_required') readonly_fields = ('communicated_at',) @admin.register(InsuranceApprovalRequest) class InsuranceApprovalRequestAdmin(admin.ModelAdmin): list_display = ( 'approval_number', 'patient_link', 'request_type', 'status_badge', 'priority_badge', 'insurance_company', 'submitted_date', 'decision_date', 'expiration_status', 'assigned_to' ) list_filter = ( 'status', 'priority', 'request_type', 'is_urgent', 'is_expedited', 'requires_peer_review', 'submitted_date', 'decision_date' ) search_fields = ( 'approval_number', 'authorization_number', 'reference_number', 'patient__first_name', 'patient__last_name', 'patient__mrn', 'insurance_info__insurance_company', 'service_description' ) readonly_fields = ( 'approval_id', 'approval_number', 'created_at', 'updated_at', 'created_by', 'turnaround_time_days', 'days_until_expiry' ) fieldsets = ( ('Identification', { 'fields': ('approval_id', 'approval_number', 'tenant') }), ('Patient & Insurance', { 'fields': ('patient', 'insurance_info') }), ('Order Information', { 'fields': ('content_type', 'object_id', 'request_type', 'service_description') }), ('Medical Codes', { 'fields': ('procedure_codes', 'diagnosis_codes') }), ('Clinical Information', { 'fields': ('clinical_justification', 'medical_necessity', 'alternative_treatments_tried') }), ('Requested Services', { 'fields': ( 'requested_quantity', 'requested_visits', 'requested_units', 'service_start_date', 'service_end_date' ) }), ('Status & Priority', { 'fields': ('status', 'priority', 'is_urgent', 'is_expedited', 'requires_peer_review') }), ('Submission', { 'fields': ('submission_method', 'submitted_date', 'submitted_by') }), ('Insurance Response', { 'fields': ( 'decision_date', 'authorization_number', 'reference_number', 'approved_quantity', 'approved_visits', 'approved_units', 'approved_amount', 'effective_date', 'expiration_date' ) }), ('Denial & Appeal', { 'fields': ('denial_reason', 'denial_code', 'appeal_date', 'appeal_reason', 'appeal_deadline'), 'classes': ('collapse',) }), ('Assignment & Tracking', { 'fields': ('assigned_to', 'requesting_provider') }), ('Communication', { 'fields': ('last_contact_date', 'last_contact_method', 'last_contact_notes'), 'classes': ('collapse',) }), ('Notes', { 'fields': ('internal_notes', 'insurance_notes'), 'classes': ('collapse',) }), ('Metadata', { 'fields': ('created_at', 'updated_at', 'created_by', 'turnaround_time_days', 'days_until_expiry'), 'classes': ('collapse',) }) ) inlines = [ApprovalDocumentInline, ApprovalStatusHistoryInline, ApprovalCommunicationLogInline] def patient_link(self, obj): url = reverse('admin:patients_patientprofile_change', args=[obj.patient.id]) return format_html('{}', url, obj.patient.get_full_name()) patient_link.short_description = 'Patient' def insurance_company(self, obj): return obj.insurance_info.insurance_company insurance_company.short_description = 'Insurance' def status_badge(self, obj): colors = { 'DRAFT': 'gray', 'PENDING_SUBMISSION': 'orange', 'SUBMITTED': 'blue', 'UNDER_REVIEW': 'blue', 'ADDITIONAL_INFO_REQUESTED': 'orange', 'APPROVED': 'green', 'PARTIALLY_APPROVED': 'lightgreen', 'DENIED': 'red', 'APPEALED': 'purple', 'APPEAL_APPROVED': 'green', 'APPEAL_DENIED': 'red', 'EXPIRED': 'darkgray', 'CANCELLED': 'gray' } color = colors.get(obj.status, 'gray') return format_html( '{}', color, obj.get_status_display() ) status_badge.short_description = 'Status' def priority_badge(self, obj): colors = { 'ROUTINE': 'green', 'URGENT': 'orange', 'STAT': 'red', 'EMERGENCY': 'darkred' } color = colors.get(obj.priority, 'gray') return format_html( '{}', color, obj.get_priority_display() ) priority_badge.short_description = 'Priority' def expiration_status(self, obj): if not obj.expiration_date: return '-' if obj.is_expired: return format_html('Expired') elif obj.is_expiring_soon: days = obj.days_until_expiry return format_html('Expires in {} days', days) else: return format_html('Valid') expiration_status.short_description = 'Expiration' def save_model(self, request, obj, form, change): if not change: obj.created_by = request.user super().save_model(request, obj, form, change) @admin.register(ApprovalDocument) class ApprovalDocumentAdmin(admin.ModelAdmin): list_display = ('title', 'approval_request', 'document_type', 'file_size_mb', 'uploaded_at', 'uploaded_by') list_filter = ('document_type', 'uploaded_at') search_fields = ('title', 'description', 'approval_request__approval_number') readonly_fields = ('document_id', 'file_size_mb', 'uploaded_at', 'uploaded_by') def save_model(self, request, obj, form, change): if not change: obj.uploaded_by = request.user if obj.file: obj.file_size = obj.file.size obj.mime_type = obj.file.content_type or 'application/octet-stream' super().save_model(request, obj, form, change) @admin.register(ApprovalStatusHistory) class ApprovalStatusHistoryAdmin(admin.ModelAdmin): list_display = ('approval_request', 'from_status', 'to_status', 'changed_at', 'changed_by') list_filter = ('to_status', 'changed_at') search_fields = ('approval_request__approval_number', 'reason', 'notes') readonly_fields = ('changed_at', 'changed_by') def save_model(self, request, obj, form, change): if not change: obj.changed_by = request.user super().save_model(request, obj, form, change) @admin.register(ApprovalCommunicationLog) class ApprovalCommunicationLogAdmin(admin.ModelAdmin): list_display = ( 'approval_request', 'communication_type', 'subject', 'contact_person', 'communicated_at', 'follow_up_badge' ) list_filter = ('communication_type', 'follow_up_required', 'communicated_at') search_fields = ( 'approval_request__approval_number', 'subject', 'message', 'contact_person' ) readonly_fields = ('communication_id', 'communicated_at', 'communicated_by') fieldsets = ( ('Approval Request', { 'fields': ('approval_request',) }), ('Communication Details', { 'fields': ( 'communication_id', 'communication_type', 'contact_person', 'contact_number', 'subject', 'message', 'response' ) }), ('Outcome & Follow-up', { 'fields': ('outcome', 'follow_up_required', 'follow_up_date') }), ('Metadata', { 'fields': ('communicated_at', 'communicated_by') }) ) def follow_up_badge(self, obj): if obj.follow_up_required: if obj.follow_up_date and obj.follow_up_date < timezone.now().date(): return format_html('Overdue') return format_html('Required') return format_html('None') follow_up_badge.short_description = 'Follow-up' def save_model(self, request, obj, form, change): if not change: obj.communicated_by = request.user super().save_model(request, obj, form, change) @admin.register(ApprovalTemplate) class ApprovalTemplateAdmin(admin.ModelAdmin): list_display = ('name', 'request_type', 'insurance_company', 'is_active', 'usage_count', 'created_at') list_filter = ('request_type', 'is_active', 'created_at') search_fields = ('name', 'description', 'insurance_company') readonly_fields = ('template_id', 'usage_count', 'created_at', 'updated_at', 'created_by') fieldsets = ( ('Template Information', { 'fields': ('template_id', 'name', 'description', 'tenant') }), ('Scope', { 'fields': ('request_type', 'insurance_company') }), ('Template Content', { 'fields': ( 'clinical_justification_template', 'medical_necessity_template', 'required_documents', 'required_codes' ) }), ('Status & Usage', { 'fields': ('is_active', 'usage_count') }), ('Metadata', { 'fields': ('created_at', 'updated_at', 'created_by'), 'classes': ('collapse',) }) ) def save_model(self, request, obj, form, change): if not change: obj.created_by = request.user super().save_model(request, obj, form, change)