""" Admin configuration for EMR app. """ from django.contrib import admin from django.utils.html import format_html from django.urls import reverse from django.utils.safestring import mark_safe from .models import ( Encounter, VitalSigns, ProblemList, CarePlan, ClinicalNote, NoteTemplate, Icd10 ) admin.site.register(Icd10) @admin.register(Encounter) class EncounterAdmin(admin.ModelAdmin): """ Admin interface for Encounter model. """ list_display = [ 'encounter_id', 'patient_name', 'provider_name', 'encounter_type', 'status', 'start_datetime', 'duration_display', 'documentation_complete' ] list_filter = [ 'tenant', 'encounter_type', 'encounter_class', 'status', 'priority', 'documentation_complete', 'signed_off' ] search_fields = [ 'patient__first_name', 'patient__last_name', 'patient__mrn', 'provider__first_name', 'provider__last_name', 'chief_complaint', 'reason_for_visit' ] readonly_fields = ['encounter_id', 'created_at', 'updated_at', 'duration_display'] fieldsets = ( ('Basic Information', { 'fields': ( 'encounter_id', 'tenant', 'patient', 'provider', 'encounter_type', 'encounter_class' ) }), ('Timing', { 'fields': ( 'start_datetime', 'end_datetime', 'duration_display' ) }), ('Status', { 'fields': ( 'status', 'priority', 'acuity_level' ) }), ('Location', { 'fields': ( 'location', 'room_number' ) }), ('Related Records', { 'fields': ( 'appointment', 'admission' ) }), ('Clinical Information', { 'fields': ( 'chief_complaint', 'reason_for_visit' ) }), ('Documentation', { 'fields': ( 'documentation_complete', 'signed_off', 'signed_by', 'signed_datetime' ) }), ('Billing', { 'fields': ( 'billable', 'billing_codes' ) }), ('Quality', { 'fields': ( 'quality_measures', ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at', 'created_by' ) }), ) def patient_name(self, obj): return obj.patient.get_full_name() patient_name.short_description = 'Patient' def provider_name(self, obj): return obj.provider.get_full_name() provider_name.short_description = 'Provider' def duration_display(self, obj): duration = obj.duration if duration: hours = duration.total_seconds() // 3600 minutes = (duration.total_seconds() % 3600) // 60 return f"{int(hours)}h {int(minutes)}m" return "Ongoing" if obj.is_active else "Not set" duration_display.short_description = 'Duration' @admin.register(VitalSigns) class VitalSignsAdmin(admin.ModelAdmin): """ Admin interface for VitalSigns model. """ list_display = [ 'measurement_id', 'patient_name', 'measured_datetime', 'temperature', 'blood_pressure_display', 'heart_rate', 'respiratory_rate', 'oxygen_saturation', 'measured_by_name' ] list_filter = [ 'measured_datetime', 'temperature_method', 'bp_position', 'oxygen_delivery', 'device_calibrated' ] search_fields = [ 'patient__first_name', 'patient__last_name', 'patient__mrn', 'measured_by__first_name', 'measured_by__last_name' ] readonly_fields = ['measurement_id', 'bmi', 'created_at', 'updated_at'] fieldsets = ( ('Basic Information', { 'fields': ( 'measurement_id', 'encounter', 'patient', 'measured_datetime' ) }), ('Temperature', { 'fields': ( 'temperature', 'temperature_method' ) }), ('Blood Pressure', { 'fields': ( 'systolic_bp', 'diastolic_bp', 'bp_position', 'bp_cuff_size' ) }), ('Heart Rate', { 'fields': ( 'heart_rate', 'heart_rhythm' ) }), ('Respiratory', { 'fields': ( 'respiratory_rate', 'oxygen_saturation', 'oxygen_delivery', 'oxygen_flow_rate' ) }), ('Pain Assessment', { 'fields': ( 'pain_scale', 'pain_location', 'pain_quality' ) }), ('Anthropometric', { 'fields': ( 'weight', 'height', 'bmi', 'head_circumference' ) }), ('Device Information', { 'fields': ( 'device_used', 'device_calibrated' ) }), ('Staff', { 'fields': ( 'measured_by', 'verified_by' ) }), ('Quality', { 'fields': ( 'critical_values', 'alerts_generated', 'notes' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at' ) }), ) def patient_name(self, obj): return obj.patient.get_full_name() patient_name.short_description = 'Patient' def blood_pressure_display(self, obj): return obj.blood_pressure or "Not recorded" blood_pressure_display.short_description = 'Blood Pressure' def measured_by_name(self, obj): return obj.measured_by.get_full_name() measured_by_name.short_description = 'Measured By' @admin.register(ProblemList) class ProblemListAdmin(admin.ModelAdmin): """ Admin interface for ProblemList model. """ list_display = [ 'problem_id', 'patient_name', 'problem_name', 'problem_type', 'status', 'severity', 'priority', 'onset_date', 'diagnosing_provider_name' ] list_filter = [ 'tenant', 'problem_type', 'status', 'severity', 'priority', 'coding_system', 'verified' ] search_fields = [ 'patient__first_name', 'patient__last_name', 'patient__mrn', 'problem_name', 'problem_code', 'diagnosing_provider__first_name', 'diagnosing_provider__last_name' ] readonly_fields = ['problem_id', 'created_at', 'updated_at'] fieldsets = ( ('Basic Information', { 'fields': ( 'problem_id', 'tenant', 'patient', 'problem_name' ) }), ('Coding', { 'fields': ( 'problem_code', 'coding_system' ) }), ('Classification', { 'fields': ( 'problem_type', 'severity', 'priority' ) }), ('Clinical Information', { 'fields': ( 'onset_date', 'onset_description', 'body_site', 'laterality' ) }), ('Status', { 'fields': ( 'status', 'resolution_date', 'resolution_notes' ) }), ('Providers', { 'fields': ( 'diagnosing_provider', 'managing_provider' ) }), ('Related Information', { 'fields': ( 'related_encounter', ) }), ('Documentation', { 'fields': ( 'clinical_notes', 'patient_concerns' ) }), ('Goals and Outcomes', { 'fields': ( 'treatment_goals', 'outcome_measures' ) }), ('Verification', { 'fields': ( 'verified', 'verified_by', 'verified_date' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at', 'created_by' ) }), ) def patient_name(self, obj): return obj.patient.get_full_name() patient_name.short_description = 'Patient' def diagnosing_provider_name(self, obj): return obj.diagnosing_provider.get_full_name() diagnosing_provider_name.short_description = 'Diagnosing Provider' @admin.register(CarePlan) class CarePlanAdmin(admin.ModelAdmin): """ Admin interface for CarePlan model. """ list_display = [ 'care_plan_id', 'patient_name', 'title', 'plan_type', 'status', 'priority', 'start_date', 'completion_percentage', 'primary_provider_name' ] list_filter = [ 'tenant', 'plan_type', 'category', 'status', 'priority', 'approved' ] search_fields = [ 'patient__first_name', 'patient__last_name', 'patient__mrn', 'title', 'description', 'primary_provider__first_name', 'primary_provider__last_name' ] readonly_fields = ['care_plan_id', 'created_at', 'updated_at'] filter_horizontal = ['care_team', 'related_problems'] fieldsets = ( ('Basic Information', { 'fields': ( 'care_plan_id', 'tenant', 'patient', 'title', 'description' ) }), ('Plan Type', { 'fields': ( 'plan_type', 'category', 'priority' ) }), ('Timing', { 'fields': ( 'start_date', 'end_date', 'target_completion_date' ) }), ('Status', { 'fields': ( 'status', 'completion_percentage' ) }), ('Providers', { 'fields': ( 'primary_provider', 'care_team' ) }), ('Related Problems', { 'fields': ( 'related_problems', ) }), ('Goals and Objectives', { 'fields': ( 'goals', 'objectives' ) }), ('Interventions', { 'fields': ( 'interventions', 'activities' ) }), ('Monitoring', { 'fields': ( 'monitoring_parameters', 'evaluation_criteria' ) }), ('Patient Involvement', { 'fields': ( 'patient_goals', 'patient_preferences', 'patient_barriers' ) }), ('Resources', { 'fields': ( 'resources_needed', 'support_systems' ) }), ('Progress', { 'fields': ( 'progress_notes', 'last_reviewed', 'next_review_date' ) }), ('Outcomes', { 'fields': ( 'outcomes_achieved', ) }), ('Approval', { 'fields': ( 'approved', 'approved_by', 'approved_date' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at', 'created_by' ) }), ) def patient_name(self, obj): return obj.patient.get_full_name() patient_name.short_description = 'Patient' def primary_provider_name(self, obj): return obj.primary_provider.get_full_name() primary_provider_name.short_description = 'Primary Provider' @admin.register(ClinicalNote) class ClinicalNoteAdmin(admin.ModelAdmin): """ Admin interface for ClinicalNote model. """ list_display = [ 'note_id', 'patient_name', 'title', 'note_type', 'status', 'author_name', 'note_datetime', 'word_count_display', 'electronically_signed' ] list_filter = [ 'note_type', 'status', 'electronically_signed', 'confidential', 'restricted_access', 'note_datetime' ] search_fields = [ 'patient__first_name', 'patient__last_name', 'patient__mrn', 'title', 'content', 'author__first_name', 'author__last_name' ] readonly_fields = ['note_id', 'word_count_display', 'created_at', 'updated_at'] filter_horizontal = ['co_signers', 'related_problems', 'related_care_plans'] fieldsets = ( ('Basic Information', { 'fields': ( 'note_id', 'encounter', 'patient', 'note_type', 'title' ) }), ('Content', { 'fields': ( 'content', 'word_count_display' ) }), ('Template', { 'fields': ( 'template', 'structured_data' ) }), ('Provider Information', { 'fields': ( 'author', 'co_signers' ) }), ('Status', { 'fields': ( 'status', 'note_datetime' ) }), ('Signatures', { 'fields': ( 'electronically_signed', 'signed_datetime', 'signature_method' ) }), ('Amendment', { 'fields': ( 'amended_note', 'amendment_reason' ) }), ('Quality', { 'fields': ( 'quality_score', 'compliance_flags' ) }), ('Privacy', { 'fields': ( 'confidential', 'restricted_access', 'access_restrictions' ) }), ('Related Information', { 'fields': ( 'related_problems', 'related_care_plans' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at' ) }), ) def patient_name(self, obj): return obj.patient.get_full_name() patient_name.short_description = 'Patient' def author_name(self, obj): return obj.author.get_full_name() author_name.short_description = 'Author' def word_count_display(self, obj): return f"{obj.word_count} words" word_count_display.short_description = 'Word Count' @admin.register(NoteTemplate) class NoteTemplateAdmin(admin.ModelAdmin): """ Admin interface for NoteTemplate model. """ list_display = [ 'template_id', 'name', 'note_type', 'specialty', 'is_active', 'is_default', 'version', 'usage_count' ] list_filter = [ 'tenant', 'note_type', 'specialty', 'is_active', 'is_default' ] search_fields = [ 'name', 'description', 'template_content' ] readonly_fields = ['template_id', 'usage_count', 'created_at', 'updated_at'] fieldsets = ( ('Basic Information', { 'fields': ( 'template_id', 'tenant', 'name', 'description' ) }), ('Template Type', { 'fields': ( 'note_type', 'specialty' ) }), ('Content', { 'fields': ( 'template_content', 'structured_fields' ) }), ('Usage', { 'fields': ( 'is_active', 'is_default', 'usage_count' ) }), ('Version Control', { 'fields': ( 'version', 'previous_version' ) }), ('Quality', { 'fields': ( 'quality_indicators', 'compliance_requirements' ) }), ('Metadata', { 'fields': ( 'created_at', 'updated_at', 'created_by' ) }), ) # Inline admin classes for related models class VitalSignsInline(admin.TabularInline): """ Inline admin for VitalSigns. """ model = VitalSigns extra = 0 readonly_fields = ['measurement_id', 'bmi'] fields = [ 'measured_datetime', 'temperature', 'systolic_bp', 'diastolic_bp', 'heart_rate', 'respiratory_rate', 'oxygen_saturation', 'measured_by' ] class ClinicalNoteInline(admin.TabularInline): """ Inline admin for ClinicalNote. """ model = ClinicalNote extra = 0 readonly_fields = ['note_id'] fields = ['note_type', 'title', 'status', 'author', 'note_datetime'] class ProblemListInline(admin.TabularInline): """ Inline admin for ProblemList. """ model = ProblemList extra = 0 readonly_fields = ['problem_id'] fields = ['problem_name', 'problem_type', 'status', 'severity', 'diagnosing_provider'] # Add inlines to Encounter admin EncounterAdmin.inlines = [VitalSignsInline, ClinicalNoteInline, ProblemListInline]