2025-08-12 13:33:25 +03:00

223 lines
11 KiB
Python

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.")