from rest_framework import serializers from ..models import ( OperatingRoom, ORBlock, SurgicalCase, SurgicalNote, EquipmentUsage, SurgicalNoteTemplate ) class BaseSerializer(serializers.ModelSerializer): """Base serializer with common functionality""" class Meta: fields = ['id'] read_only_fields = ['created_at', 'updated_at'] class OperatingRoomSerializer(serializers.ModelSerializer): """Serializer for OperatingRoom model""" room_type_display = serializers.CharField(source='get_room_type_display', read_only=True) status_display = serializers.CharField(source='get_status_display', read_only=True) current_utilization = serializers.FloatField(read_only=True) class Meta: model = OperatingRoom fields = [ 'room_id', 'room_number', 'name', 'room_type', 'room_type_display', 'floor', 'building', 'capacity', 'length', 'width', 'height', 'status', 'status_display', 'equipment_list', 'capabilities', 'special_features', 'ventilation_type', 'lighting_type', 'temperature_range', 'humidity_range', 'last_cleaned', 'next_maintenance', 'is_active', 'current_utilization', 'created_at', 'updated_at' ] read_only_fields = ['room_id', 'current_utilization', 'created_at', 'updated_at'] class ORBlockSerializer(serializers.ModelSerializer): """Serializer for ORBlock model""" operating_room_number = serializers.CharField(source='operating_room.room_number', read_only=True) primary_surgeon_name = serializers.CharField(source='primary_surgeon.get_full_name', read_only=True) utilization_percentage = serializers.FloatField(read_only=True) class Meta: model = ORBlock fields = [ 'block_id', 'operating_room', 'operating_room_number', 'date', 'start_time', 'end_time', 'primary_surgeon', 'primary_surgeon_name', 'block_type', 'specialty', 'allocated_minutes', 'used_minutes', 'utilization_percentage', 'is_emergency_block', 'notes', 'created_at', 'updated_at' ] read_only_fields = ['block_id', 'utilization_percentage', 'created_at', 'updated_at'] class SurgicalCaseSerializer(serializers.ModelSerializer): """Serializer for SurgicalCase model""" patient_name = serializers.CharField(source='patient.get_full_name', read_only=True) patient_mrn = serializers.CharField(source='patient.mrn', read_only=True) primary_surgeon_name = serializers.CharField(source='primary_surgeon.get_full_name', read_only=True) operating_room_number = serializers.CharField(source='operating_room.room_number', 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) case_type_display = serializers.CharField(source='get_case_type_display', read_only=True) duration_minutes = serializers.IntegerField(read_only=True) class Meta: model = SurgicalCase fields = [ 'case_id', 'case_number', 'patient', 'patient_name', 'patient_mrn', 'primary_surgeon', 'primary_surgeon_name', 'assisting_surgeons', 'anesthesiologist', 'scrub_nurse', 'circulating_nurse', 'operating_room', 'operating_room_number', 'or_block', 'scheduled_date', 'scheduled_start_time', 'scheduled_end_time', 'actual_start_time', 'actual_end_time', 'duration_minutes', 'procedure_name', 'procedure_codes', 'case_type', 'case_type_display', 'priority', 'priority_display', 'status', 'status_display', 'anesthesia_type', 'position', 'special_equipment', 'estimated_blood_loss', 'complications', 'postop_destination', 'notes', 'created_at', 'updated_at' ] read_only_fields = ['case_id', 'case_number', 'duration_minutes', 'created_at', 'updated_at'] class SurgicalNoteTemplateSerializer(serializers.ModelSerializer): """Serializer for SurgicalNoteTemplate model""" class Meta: model = SurgicalNoteTemplate fields = [ 'template_id', 'name', 'description', 'procedure_type', 'specialty', 'template_content', 'sections', 'required_fields', 'is_active', 'created_by', 'created_at', 'updated_at' ] read_only_fields = ['template_id', 'created_at', 'updated_at'] class SurgicalNoteSerializer(serializers.ModelSerializer): """Serializer for SurgicalNote model""" surgical_case_number = serializers.CharField(source='surgical_case.case_number', read_only=True) patient_name = serializers.CharField(source='surgical_case.patient.get_full_name', read_only=True) surgeon_name = serializers.CharField(source='surgeon.get_full_name', read_only=True) note_type_display = serializers.CharField(source='get_note_type_display', read_only=True) class Meta: model = SurgicalNote fields = [ 'note_id', 'surgical_case', 'surgical_case_number', 'patient_name', 'template', 'surgeon', 'surgeon_name', 'note_type', 'note_type_display', 'preoperative_diagnosis', 'postoperative_diagnosis', 'procedure_performed', 'indications', 'findings', 'technique', 'complications', 'estimated_blood_loss', 'specimens', 'implants', 'drains', 'closure', 'postoperative_plan', 'dictated_date', 'transcribed_date', 'signed_date', 'is_signed', 'electronic_signature', 'created_at', 'updated_at' ] read_only_fields = ['note_id', 'created_at', 'updated_at'] class EquipmentUsageSerializer(serializers.ModelSerializer): """Serializer for EquipmentUsage model""" surgical_case_number = serializers.CharField(source='surgical_case.case_number', read_only=True) used_by_name = serializers.CharField(source='used_by.get_full_name', read_only=True) class Meta: model = EquipmentUsage fields = [ 'usage_id', 'surgical_case', 'surgical_case_number', 'equipment_name', 'equipment_id', 'serial_number', 'start_time', 'end_time', 'duration_minutes', 'used_by', 'used_by_name', 'status', 'maintenance_required', 'issues_reported', 'notes', 'created_at', 'updated_at' ] read_only_fields = ['usage_id', 'duration_minutes', 'created_at', 'updated_at'] class ORStatsSerializer(serializers.Serializer): """Serializer for operating room statistics""" total_cases = serializers.IntegerField() cases_today = serializers.IntegerField() emergency_cases = serializers.IntegerField() completed_cases = serializers.IntegerField() cancelled_cases = serializers.IntegerField() average_duration = serializers.FloatField() room_utilization = serializers.DictField() surgeon_productivity = serializers.ListField() case_types = serializers.DictField() status_breakdown = serializers.DictField() class CaseSchedulingSerializer(serializers.Serializer): """Serializer for scheduling surgical cases""" patient_id = serializers.IntegerField() primary_surgeon_id = serializers.IntegerField() operating_room_id = serializers.IntegerField() scheduled_date = serializers.DateField() scheduled_start_time = serializers.TimeField() estimated_duration = serializers.IntegerField() procedure_name = serializers.CharField() procedure_codes = serializers.CharField() case_type = serializers.CharField() priority = serializers.CharField() anesthesia_type = serializers.CharField() special_equipment = serializers.CharField(required=False, allow_blank=True) notes = serializers.CharField(required=False, allow_blank=True) def validate_estimated_duration(self, value): """Validate estimated duration""" if value <= 0: raise serializers.ValidationError("Estimated duration must be greater than 0.") if value > 720: # 12 hours raise serializers.ValidationError("Estimated duration cannot exceed 12 hours.") return value class CaseStartSerializer(serializers.Serializer): """Serializer for starting surgical cases""" case_id = serializers.IntegerField() anesthesiologist_id = serializers.IntegerField(required=False) scrub_nurse_id = serializers.IntegerField(required=False) circulating_nurse_id = serializers.IntegerField(required=False) position = serializers.CharField(required=False, allow_blank=True) notes = serializers.CharField(required=False, allow_blank=True) def validate_case_id(self, value): """Validate that the case exists and can be started""" try: case = SurgicalCase.objects.get(id=value) if case.status not in ['SCHEDULED', 'PATIENT_IN_ROOM']: raise serializers.ValidationError( "Case cannot be started with current status." ) return value except SurgicalCase.DoesNotExist: raise serializers.ValidationError("Invalid case ID.") class CaseCompletionSerializer(serializers.Serializer): """Serializer for completing surgical cases""" case_id = serializers.IntegerField() estimated_blood_loss = serializers.IntegerField(required=False) complications = serializers.CharField(required=False, allow_blank=True) postop_destination = serializers.CharField(required=False, allow_blank=True) notes = serializers.CharField(required=False, allow_blank=True) def validate_case_id(self, value): """Validate that the case exists and can be completed""" try: case = SurgicalCase.objects.get(id=value) if case.status != 'IN_PROGRESS': raise serializers.ValidationError( "Case must be in progress to complete." ) return value except SurgicalCase.DoesNotExist: raise serializers.ValidationError("Invalid case ID.") class SurgicalNoteDictationSerializer(serializers.Serializer): """Serializer for dictating surgical notes""" case_id = serializers.IntegerField() template_id = serializers.IntegerField(required=False) note_type = serializers.CharField() preoperative_diagnosis = serializers.CharField() postoperative_diagnosis = serializers.CharField() procedure_performed = serializers.CharField() indications = serializers.CharField() findings = serializers.CharField() technique = serializers.CharField() complications = serializers.CharField(required=False, allow_blank=True) estimated_blood_loss = serializers.IntegerField(required=False) specimens = serializers.CharField(required=False, allow_blank=True) implants = serializers.CharField(required=False, allow_blank=True) drains = serializers.CharField(required=False, allow_blank=True) closure = serializers.CharField() postoperative_plan = serializers.CharField() def validate_case_id(self, value): """Validate that the case exists and can have notes""" try: case = SurgicalCase.objects.get(id=value) if case.status not in ['IN_PROGRESS', 'COMPLETED']: raise serializers.ValidationError( "Case must be in progress or completed to create notes." ) return value except SurgicalCase.DoesNotExist: raise serializers.ValidationError("Invalid case ID.") class EquipmentTrackingSerializer(serializers.Serializer): """Serializer for tracking equipment usage""" case_id = serializers.IntegerField() equipment_name = serializers.CharField() equipment_id = serializers.CharField() serial_number = serializers.CharField(required=False, allow_blank=True) start_time = serializers.DateTimeField() end_time = serializers.DateTimeField(required=False) maintenance_required = serializers.BooleanField(default=False) issues_reported = serializers.CharField(required=False, allow_blank=True) notes = serializers.CharField(required=False, allow_blank=True) def validate(self, data): """Validate equipment tracking data""" if data.get('end_time') and data.get('start_time'): if data['end_time'] <= data['start_time']: raise serializers.ValidationError( "End time must be after start time." ) return data