from rest_framework import serializers from ..models import ( ImagingStudy, ImagingSeries, DICOMImage, RadiologyReport, ReportTemplate, ImagingOrder ) class BaseSerializer(serializers.ModelSerializer): """Base serializer with common functionality""" class Meta: fields = ['id'] read_only_fields = ['created_at', 'updated_at'] class ImagingOrderSerializer(serializers.ModelSerializer): """Serializer for ImagingOrder model""" patient_name = serializers.CharField(source='patient.get_full_name', read_only=True) patient_mrn = serializers.CharField(source='patient.mrn', read_only=True) ordering_provider_name = serializers.CharField(source='ordering_provider.get_full_name', read_only=True) status_display = serializers.CharField(source='get_status_display', read_only=True) priority_display = serializers.CharField(source='get_priority_display', read_only=True) modality_display = serializers.CharField(source='get_modality_display', read_only=True) class Meta: model = ImagingOrder fields = [ 'order_id', 'order_number', 'patient', 'patient_name', 'patient_mrn', 'encounter', 'ordering_provider', 'ordering_provider_name', 'order_date', 'scheduled_date', 'completed_date', 'status', 'status_display', 'priority', 'priority_display', 'modality', 'modality_display', 'body_part', 'clinical_indication', 'clinical_history', 'diagnosis_codes', 'contrast_required', 'contrast_type', 'special_instructions', 'technologist_notes', 'radiologist_notes', 'estimated_duration', 'location', 'room_number', 'equipment_id', 'protocol_name', 'created_at', 'updated_at' ] read_only_fields = ['order_id', 'order_number', 'created_at', 'updated_at'] class ImagingStudySerializer(serializers.ModelSerializer): """Serializer for ImagingStudy model""" order_number = serializers.CharField(source='imaging_order.order_number', read_only=True) patient_name = serializers.CharField(source='imaging_order.patient.get_full_name', read_only=True) modality_display = serializers.CharField(source='get_modality_display', read_only=True) status_display = serializers.CharField(source='get_status_display', read_only=True) performed_by_name = serializers.CharField(source='performed_by.get_full_name', read_only=True) class Meta: model = ImagingStudy fields = [ 'study_id', 'study_instance_uid', 'imaging_order', 'order_number', 'patient_name', 'accession_number', 'study_date', 'study_time', 'modality', 'modality_display', 'body_part_examined', 'study_description', 'protocol_name', 'series_count', 'images_count', 'status', 'status_display', 'performed_by', 'performed_by_name', 'performing_location', 'equipment_manufacturer', 'equipment_model', 'equipment_serial', 'contrast_used', 'contrast_agent', 'contrast_volume', 'radiation_dose', 'kvp', 'mas', 'slice_thickness', 'pixel_spacing', 'image_orientation', 'patient_position', 'study_comments', 'created_at', 'updated_at' ] read_only_fields = ['study_id', 'study_instance_uid', 'created_at', 'updated_at'] class ImagingSeriesSerializer(serializers.ModelSerializer): """Serializer for ImagingSeries model""" study_accession = serializers.CharField(source='imaging_study.accession_number', read_only=True) modality_display = serializers.CharField(source='get_modality_display', read_only=True) class Meta: model = ImagingSeries fields = [ 'series_id', 'series_instance_uid', 'imaging_study', 'study_accession', 'series_number', 'series_date', 'series_time', 'modality', 'modality_display', 'series_description', 'body_part_examined', 'patient_position', 'images_count', 'slice_thickness', 'slice_spacing', 'pixel_spacing', 'image_orientation', 'rows', 'columns', 'bits_allocated', 'bits_stored', 'photometric_interpretation', 'samples_per_pixel', 'planar_configuration', 'window_center', 'window_width', 'rescale_intercept', 'rescale_slope', 'series_comments', 'created_at', 'updated_at' ] read_only_fields = ['series_id', 'series_instance_uid', 'created_at', 'updated_at'] class DICOMImageSerializer(serializers.ModelSerializer): """Serializer for DICOMImage model""" series_description = serializers.CharField(source='imaging_series.series_description', read_only=True) study_accession = serializers.CharField(source='imaging_series.imaging_study.accession_number', read_only=True) class Meta: model = DICOMImage fields = [ 'image_id', 'sop_instance_uid', 'imaging_series', 'series_description', 'study_accession', 'instance_number', 'image_position', 'image_orientation', 'pixel_spacing', 'slice_thickness', 'slice_location', 'rows', 'columns', 'bits_allocated', 'bits_stored', 'high_bit', 'pixel_representation', 'photometric_interpretation', 'samples_per_pixel', 'planar_configuration', 'window_center', 'window_width', 'rescale_intercept', 'rescale_slope', 'file_path', 'file_size', 'transfer_syntax', 'compression_type', 'image_comments', 'created_at', 'updated_at' ] read_only_fields = ['image_id', 'sop_instance_uid', 'created_at', 'updated_at'] class ReportTemplateSerializer(serializers.ModelSerializer): """Serializer for ReportTemplate model""" modality_display = serializers.CharField(source='get_modality_display', read_only=True) class Meta: model = ReportTemplate fields = [ 'template_id', 'name', 'description', 'modality', 'modality_display', 'body_part', 'procedure_type', 'template_content', 'sections', 'macros', 'is_active', 'created_by', 'created_at', 'updated_at' ] read_only_fields = ['template_id', 'created_at', 'updated_at'] class RadiologyReportSerializer(serializers.ModelSerializer): """Serializer for RadiologyReport model""" study_accession = serializers.CharField(source='imaging_study.accession_number', read_only=True) patient_name = serializers.CharField(source='imaging_study.imaging_order.patient.get_full_name', read_only=True) radiologist_name = serializers.CharField(source='radiologist.get_full_name', read_only=True) status_display = serializers.CharField(source='get_status_display', read_only=True) class Meta: model = RadiologyReport fields = [ 'report_id', 'imaging_study', 'study_accession', 'patient_name', 'report_template', 'radiologist', 'radiologist_name', 'dictated_date', 'transcribed_date', 'signed_date', 'status', 'status_display', 'clinical_history', 'technique', 'findings', 'impression', 'recommendations', 'comparison_studies', 'addendum', 'critical_result', 'communication_log', 'voice_file_path', 'created_at', 'updated_at' ] read_only_fields = ['report_id', 'created_at', 'updated_at'] class RadiologyStatsSerializer(serializers.Serializer): """Serializer for radiology statistics""" total_orders = serializers.IntegerField() pending_orders = serializers.IntegerField() completed_today = serializers.IntegerField() studies_performed = serializers.IntegerField() reports_pending = serializers.IntegerField() critical_results = serializers.IntegerField() average_turnaround = serializers.FloatField() equipment_utilization = serializers.DictField() modality_breakdown = serializers.DictField() status_breakdown = serializers.DictField() class StudySchedulingSerializer(serializers.Serializer): """Serializer for scheduling imaging studies""" order_id = serializers.IntegerField() scheduled_date = serializers.DateTimeField() location = serializers.CharField() room_number = serializers.CharField() equipment_id = serializers.CharField() special_instructions = serializers.CharField(required=False, allow_blank=True) def validate_order_id(self, value): """Validate that the order exists and can be scheduled""" try: order = ImagingOrder.objects.get(id=value) if order.status not in ['PENDING', 'SCHEDULED']: raise serializers.ValidationError( "Order cannot be scheduled with current status." ) return value except ImagingOrder.DoesNotExist: raise serializers.ValidationError("Invalid order ID.") class StudyCompletionSerializer(serializers.Serializer): """Serializer for completing imaging studies""" study_id = serializers.IntegerField() contrast_used = serializers.BooleanField(default=False) contrast_agent = serializers.CharField(required=False, allow_blank=True) contrast_volume = serializers.DecimalField(max_digits=8, decimal_places=2, required=False) radiation_dose = serializers.DecimalField(max_digits=10, decimal_places=4, required=False) study_comments = serializers.CharField(required=False, allow_blank=True) def validate_study_id(self, value): """Validate that the study exists and can be completed""" try: study = ImagingStudy.objects.get(id=value) if study.status != 'IN_PROGRESS': raise serializers.ValidationError( "Study must be in progress to complete." ) return value except ImagingStudy.DoesNotExist: raise serializers.ValidationError("Invalid study ID.") class ReportDictationSerializer(serializers.Serializer): """Serializer for dictating radiology reports""" study_id = serializers.IntegerField() template_id = serializers.IntegerField(required=False) clinical_history = serializers.CharField() technique = serializers.CharField() findings = serializers.CharField() impression = serializers.CharField() recommendations = serializers.CharField(required=False, allow_blank=True) comparison_studies = serializers.CharField(required=False, allow_blank=True) critical_result = serializers.BooleanField(default=False) def validate_study_id(self, value): """Validate that the study exists and can have a report""" try: study = ImagingStudy.objects.get(id=value) if study.status != 'COMPLETED': raise serializers.ValidationError( "Study must be completed to create report." ) return value except ImagingStudy.DoesNotExist: raise serializers.ValidationError("Invalid study ID.")