223 lines
11 KiB
Python
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.")
|
|
|