""" Surveys serializers """ from rest_framework import serializers from .models import SurveyInstance, SurveyQuestion, SurveyResponse, SurveyTemplate class SurveyQuestionSerializer(serializers.ModelSerializer): """Survey question serializer""" class Meta: model = SurveyQuestion fields = [ 'id', 'survey_template', 'text', 'text_ar', 'question_type', 'order', 'is_required', 'choices_json', 'weight', 'branch_logic', 'help_text', 'help_text_ar', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] class SurveyTemplateSerializer(serializers.ModelSerializer): """Survey template serializer""" hospital_name = serializers.CharField(source='hospital.name', read_only=True) questions = SurveyQuestionSerializer(many=True, read_only=True) question_count = serializers.SerializerMethodField() class Meta: model = SurveyTemplate fields = [ 'id', 'name', 'name_ar', 'description', 'description_ar', 'hospital', 'hospital_name', 'survey_type', 'scoring_method', 'negative_threshold', 'is_active', 'version', 'questions', 'question_count', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] def get_question_count(self, obj): """Get number of questions""" return obj.get_question_count() class SurveyResponseSerializer(serializers.ModelSerializer): """Survey response serializer""" question_text = serializers.CharField(source='question.text', read_only=True) question_type = serializers.CharField(source='question.question_type', read_only=True) class Meta: model = SurveyResponse fields = [ 'id', 'survey_instance', 'question', 'question_text', 'question_type', 'numeric_value', 'text_value', 'choice_value', 'response_time_seconds', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] class SurveyInstanceSerializer(serializers.ModelSerializer): """Survey instance serializer""" survey_template_name = serializers.CharField(source='survey_template.name', read_only=True) patient_name = serializers.CharField(source='patient.get_full_name', read_only=True) patient_mrn = serializers.CharField(source='patient.mrn', read_only=True) responses = SurveyResponseSerializer(many=True, read_only=True) survey_url = serializers.SerializerMethodField() class Meta: model = SurveyInstance fields = [ 'id', 'survey_template', 'survey_template_name', 'patient', 'patient_name', 'patient_mrn', 'journey_instance', 'journey_stage_instance', 'encounter_id', 'delivery_channel', 'recipient_phone', 'recipient_email', 'access_token', 'token_expires_at', 'survey_url', 'status', 'sent_at', 'opened_at', 'completed_at', 'total_score', 'is_negative', 'responses', 'metadata', 'created_at', 'updated_at' ] read_only_fields = [ 'id', 'access_token', 'token_expires_at', 'sent_at', 'opened_at', 'completed_at', 'total_score', 'is_negative', 'created_at', 'updated_at' ] def get_survey_url(self, obj): """Get survey URL""" return obj.get_survey_url() class SurveySubmissionSerializer(serializers.Serializer): """ Serializer for submitting survey responses. Used by the public survey form. """ responses = serializers.ListField( child=serializers.DictField(), help_text="Array of {question_id, numeric_value, text_value, choice_value}" ) def validate_responses(self, value): """Validate responses""" if not value: raise serializers.ValidationError("At least one response is required") for response in value: if 'question_id' not in response: raise serializers.ValidationError("Each response must have question_id") return value def create(self, validated_data): """ Create survey responses and calculate score. This is called when a patient submits the survey. """ survey_instance = self.context['survey_instance'] responses_data = validated_data['responses'] from apps.surveys.models import SurveyResponse from django.utils import timezone # Create responses for response_data in responses_data: SurveyResponse.objects.create( survey_instance=survey_instance, question_id=response_data['question_id'], numeric_value=response_data.get('numeric_value'), text_value=response_data.get('text_value', ''), choice_value=response_data.get('choice_value', ''), response_time_seconds=response_data.get('response_time_seconds') ) # Update survey instance survey_instance.status = 'completed' survey_instance.completed_at = timezone.now() survey_instance.save() # Calculate score survey_instance.calculate_score() # Queue processing task from apps.surveys.tasks import process_survey_completion process_survey_completion.delay(str(survey_instance.id)) return survey_instance class PublicSurveySerializer(serializers.ModelSerializer): """ Public survey serializer for patient-facing survey form. Excludes sensitive information. """ survey_name = serializers.CharField(source='survey_template.name', read_only=True) survey_name_ar = serializers.CharField(source='survey_template.name_ar', read_only=True) survey_description = serializers.CharField(source='survey_template.description', read_only=True) survey_description_ar = serializers.CharField(source='survey_template.description_ar', read_only=True) questions = SurveyQuestionSerializer(source='survey_template.questions', many=True, read_only=True) class Meta: model = SurveyInstance fields = [ 'id', 'survey_name', 'survey_name_ar', 'survey_description', 'survey_description_ar', 'questions', 'status', 'completed_at' ] read_only_fields = ['id', 'status', 'completed_at']