""" Radiology app admin configuration. """ 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 ( ImagingStudy, ImagingSeries, DICOMImage, RadiologyReport, ReportTemplate, ImagingOrder ) class ImagingSeriesInline(admin.TabularInline): """ Inline admin for imaging series. """ model = ImagingSeries extra = 0 fields = [ 'series_number', 'modality', 'series_description', 'number_of_instances', 'series_size', 'image_quality' ] readonly_fields = ['number_of_instances', 'series_size'] class DICOMImageInline(admin.TabularInline): """ Inline admin for DICOM images. """ model = DICOMImage extra = 0 fields = [ 'instance_number', 'rows', 'columns', 'file_size', 'image_quality', 'processed' ] readonly_fields = ['file_size'] @admin.register(ImagingStudy) class ImagingStudyAdmin(admin.ModelAdmin): """ Admin interface for imaging studies. """ list_display = [ 'accession_number', 'patient_name', 'modality', 'study_description', 'study_datetime', 'status', 'priority', 'radiologist', 'number_of_series' ] list_filter = [ 'tenant', 'modality', 'status', 'priority', 'study_datetime', 'image_quality', 'completion_status' ] search_fields = [ 'accession_number', 'study_instance_uid', 'patient__first_name', 'patient__last_name', 'patient__mrn', 'study_description' ] readonly_fields = [ 'study_id', 'accession_number', 'study_datetime', 'number_of_series', 'number_of_instances', 'study_size', 'created_at', 'updated_at' ] fieldsets = [ ('Study Information', { 'fields': [ 'study_id', 'study_instance_uid', 'accession_number', 'tenant', 'patient' ] }), ('Study Details', { 'fields': [ 'modality', 'study_description', 'body_part', 'study_datetime' ] }), ('Clinical Information', { 'fields': [ 'clinical_indication', 'clinical_history', 'diagnosis_code', 'referring_physician', 'radiologist' ] }), ('Status and Priority', { 'fields': [ 'status', 'priority', 'image_quality', 'completion_status' ] }), ('Technical Parameters', { 'fields': [ 'kvp', 'mas', 'exposure_time', 'slice_thickness' ], 'classes': ['collapse'] }), ('Equipment Information', { 'fields': [ 'station_name', 'manufacturer', 'model_name' ], 'classes': ['collapse'] }), ('Study Metrics', { 'fields': [ 'number_of_series', 'number_of_instances', 'study_size' ], 'classes': ['collapse'] }), ('PACS Information', { 'fields': [ 'pacs_location', 'archived', 'archive_location' ], 'classes': ['collapse'] }), ('Related Information', { 'fields': [ 'encounter', 'imaging_order' ], 'classes': ['collapse'] }), ('Metadata', { 'fields': [ 'created_at', 'updated_at', 'created_by' ], 'classes': ['collapse'] }) ] inlines = [ImagingSeriesInline] date_hierarchy = 'study_datetime' def patient_name(self, obj): """Display patient name.""" return obj.patient.get_full_name() patient_name.short_description = 'Patient' def get_queryset(self, request): """Filter by user's tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): qs = qs.filter(tenant=request.user.tenant) return qs.select_related('patient', 'radiologist', 'referring_physician') @admin.register(ImagingSeries) class ImagingSeriesAdmin(admin.ModelAdmin): """ Admin interface for imaging series. """ list_display = [ 'series_number', 'study_accession', 'modality', 'series_description', 'series_datetime', 'number_of_instances', 'image_quality' ] list_filter = [ 'modality', 'series_datetime', 'image_quality', 'patient_position', 'contrast_route' ] search_fields = [ 'series_instance_uid', 'series_description', 'study__accession_number', 'study__patient__first_name', 'study__patient__last_name' ] readonly_fields = [ 'series_id', 'series_datetime', 'number_of_instances', 'series_size', 'created_at', 'updated_at' ] fieldsets = [ ('Series Information', { 'fields': [ 'series_id', 'series_instance_uid', 'series_number', 'study' ] }), ('Series Details', { 'fields': [ 'modality', 'series_description', 'protocol_name', 'series_date', 'series_time', 'series_datetime' ] }), ('Technical Parameters', { 'fields': [ 'slice_thickness', 'spacing_between_slices', 'pixel_spacing', 'image_orientation' ] }), ('Body Part and Position', { 'fields': [ 'body_part', 'patient_position' ] }), ('Contrast Information', { 'fields': [ 'contrast_agent', 'contrast_route' ] }), ('Series Metrics', { 'fields': [ 'number_of_instances', 'series_size', 'image_quality' ] }), ('Metadata', { 'fields': [ 'created_at', 'updated_at' ], 'classes': ['collapse'] }) ] inlines = [DICOMImageInline] def study_accession(self, obj): """Display study accession number.""" return obj.study.accession_number study_accession.short_description = 'Study' def get_queryset(self, request): """Filter by user's tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): qs = qs.filter(study__tenant=request.user.tenant) return qs.select_related('study__patient') @admin.register(DICOMImage) class DICOMImageAdmin(admin.ModelAdmin): """ Admin interface for DICOM images. """ list_display = [ 'instance_number', 'series_info', 'sop_class_uid', 'rows', 'columns', 'file_size_mb', 'image_quality', 'processed', 'archived' ] list_filter = [ 'sop_class_uid', 'image_quality', 'processed', 'archived', 'content_date' ] search_fields = [ 'sop_instance_uid', 'series__series_instance_uid', 'series__study__accession_number' ] readonly_fields = [ 'image_id', 'file_size_mb', 'acquisition_datetime', 'created_at', 'updated_at' ] fieldsets = [ ('Image Information', { 'fields': [ 'image_id', 'sop_instance_uid', 'instance_number', 'series' ] }), ('Image Details', { 'fields': [ 'image_type', 'sop_class_uid' ] }), ('Image Dimensions', { 'fields': [ 'rows', 'columns', 'bits_allocated', 'bits_stored' ] }), ('Image Position and Orientation', { 'fields': [ 'image_position', 'image_orientation', 'slice_location' ] }), ('Window/Level Settings', { 'fields': [ 'window_center', 'window_width' ] }), ('File Information', { 'fields': [ 'file_path', 'file_size', 'file_size_mb', 'transfer_syntax_uid' ] }), ('Content Information', { 'fields': [ 'content_date', 'content_time', 'acquisition_datetime' ] }), ('Quality and Status', { 'fields': [ 'image_quality', 'processed', 'archived' ] }), ('Metadata', { 'fields': [ 'created_at', 'updated_at' ], 'classes': ['collapse'] }) ] def series_info(self, obj): """Display series information.""" return f"Series {obj.series.series_number} - {obj.series.study.accession_number}" series_info.short_description = 'Series' def get_queryset(self, request): """Filter by user's tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): qs = qs.filter(series__study__tenant=request.user.tenant) return qs.select_related('series__study') @admin.register(RadiologyReport) class RadiologyReportAdmin(admin.ModelAdmin): """ Admin interface for radiology reports. """ list_display = [ 'study_accession', 'patient_name', 'radiologist', 'status', 'critical_finding', 'finalized_datetime', 'turnaround_time' ] list_filter = [ 'status', 'critical_finding', 'critical_communicated', 'finalized_datetime', 'radiologist' ] search_fields = [ 'study__accession_number', 'study__patient__first_name', 'study__patient__last_name', 'radiologist__first_name', 'radiologist__last_name', 'findings', 'impression' ] readonly_fields = [ 'report_id', 'report_length', 'turnaround_time', 'created_at', 'updated_at' ] fieldsets = [ ('Report Information', { 'fields': [ 'report_id', 'study', 'template_used' ] }), ('Radiologist Information', { 'fields': [ 'radiologist', 'dictated_by', 'transcribed_by' ] }), ('Report Content', { 'fields': [ 'clinical_history', 'technique', 'findings', 'impression', 'recommendations' ] }), ('Report Status', { 'fields': [ 'status' ] }), ('Critical Findings', { 'fields': [ 'critical_finding', 'critical_communicated', 'critical_communicated_to', 'critical_communicated_datetime' ] }), ('Report Dates', { 'fields': [ 'dictated_datetime', 'transcribed_datetime', 'verified_datetime', 'finalized_datetime' ] }), ('Structured Reporting', { 'fields': [ 'structured_data' ], 'classes': ['collapse'] }), ('Quality and Metrics', { 'fields': [ 'report_length', 'turnaround_time' ], 'classes': ['collapse'] }), ('Addenda', { 'fields': [ 'addendum', 'addendum_datetime' ], 'classes': ['collapse'] }), ('Metadata', { 'fields': [ 'created_at', 'updated_at' ], 'classes': ['collapse'] }) ] def study_accession(self, obj): """Display study accession number.""" return obj.study.accession_number study_accession.short_description = 'Study' def patient_name(self, obj): """Display patient name.""" return obj.study.patient.get_full_name() patient_name.short_description = 'Patient' def get_queryset(self, request): """Filter by user's tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): qs = qs.filter(study__tenant=request.user.tenant) return qs.select_related('study__patient', 'radiologist') @admin.register(ReportTemplate) class ReportTemplateAdmin(admin.ModelAdmin): """ Admin interface for report templates. """ list_display = [ 'name', 'modality', 'body_part', 'is_active', 'is_default', 'usage_count', 'created_by' ] list_filter = [ 'tenant', 'modality', 'body_part', 'is_active', 'is_default' ] search_fields = [ 'name', 'description', 'findings_template', 'impression_template' ] readonly_fields = [ 'template_id', 'usage_count', 'created_at', 'updated_at' ] fieldsets = [ ('Template Information', { 'fields': [ 'template_id', 'name', 'description', 'tenant' ] }), ('Template Scope', { 'fields': [ 'modality', 'body_part' ] }), ('Template Content', { 'fields': [ 'clinical_history_template', 'technique_template', 'findings_template', 'impression_template', 'recommendations_template' ] }), ('Structured Reporting', { 'fields': [ 'structured_fields' ], 'classes': ['collapse'] }), ('Template Status', { 'fields': [ 'is_active', 'is_default' ] }), ('Usage Statistics', { 'fields': [ 'usage_count' ], 'classes': ['collapse'] }), ('Metadata', { 'fields': [ 'created_at', 'updated_at', 'created_by' ], 'classes': ['collapse'] }) ] def get_queryset(self, request): """Filter by user's tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): qs = qs.filter(tenant=request.user.tenant) return qs.select_related('created_by') @admin.register(ImagingOrder) class ImagingOrderAdmin(admin.ModelAdmin): """ Admin interface for imaging orders. """ list_display = [ 'order_number', 'patient_name', 'modality', 'study_description', 'priority', 'status', 'ordering_provider', 'order_datetime' ] list_filter = [ 'tenant', 'modality', 'priority', 'status', 'contrast_required', 'order_datetime' ] search_fields = [ 'order_number', 'patient__first_name', 'patient__last_name', 'patient__mrn', 'study_description', 'clinical_indication' ] readonly_fields = [ 'order_id', 'order_number', 'created_at', 'updated_at' ] fieldsets = [ ('Order Information', { 'fields': [ 'order_id', 'order_number', 'tenant' ] }), ('Patient and Provider', { 'fields': [ 'patient', 'ordering_provider' ] }), ('Order Details', { 'fields': [ 'order_datetime', 'priority' ] }), ('Imaging Details', { 'fields': [ 'modality', 'study_description', 'body_part' ] }), ('Clinical Information', { 'fields': [ 'clinical_indication', 'clinical_history', 'diagnosis_code' ] }), ('Contrast Information', { 'fields': [ 'contrast_required', 'contrast_type', 'contrast_route' ] }), ('Scheduling Information', { 'fields': [ 'requested_datetime', 'scheduled_datetime' ] }), ('Status', { 'fields': [ 'status' ] }), ('Related Information', { 'fields': [ 'encounter' ] }), ('Special Instructions', { 'fields': [ 'special_instructions', 'patient_preparation' ], 'classes': ['collapse'] }), ('Metadata', { 'fields': [ 'created_at', 'updated_at' ], 'classes': ['collapse'] }) ] date_hierarchy = 'order_datetime' def patient_name(self, obj): """Display patient name.""" return obj.patient.get_full_name() patient_name.short_description = 'Patient' def get_queryset(self, request): """Filter by user's tenant.""" qs = super().get_queryset(request) if hasattr(request.user, 'tenant'): qs = qs.filter(tenant=request.user.tenant) return qs.select_related('patient', 'ordering_provider') # Customize admin site admin.site.site_header = "Hospital Management System - Radiology" admin.site.site_title = "Radiology Admin" admin.site.index_title = "Radiology Administration"