127.0.0.1:55043 - - [04/Jan/2025:18:47:17] "GET /api/get_patient_appointments/" 200 4818
HTTP b'POST' request for ['127.0.0.1', 55342]
(0.063) SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 85 LIMIT 21; args=(85,); alias=default
(0.046) SELECT "myapp_doctor"."id", "myapp_doctor"."user_id", "myapp_doctor"."country", 
"myapp_doctor"."phone", "myapp_doctor"."degree", "myapp_doctor"."specialization", "myapp_doctor"."years_of_experience", "myapp_doctor"."branch", "myapp_doctor"."profile_photo", "myapp_doctor"."user_type", "myapp_doctor"."is_in_call" FROM "myapp_doctor" WHERE "myapp_doctor"."user_id" = 85 LIMIT 21; args=(85,); alias=default
(0.047) SELECT "myapp_patient"."id", "myapp_patient"."user_id", "myapp_patient"."country", "myapp_patient"."phone", "myapp_patient"."dob", "myapp_patient"."gender", "myapp_patient"."user_type", "myapp_patient"."is_in_call" FROM "myapp_patient" WHERE "myapp_patient"."id" = 38 LIMIT 21; args=(38,); alias=default
Internal Server Error: /api/diagnosis/add/
HTTP 500 response started for ['127.0.0.1', 55342]
HTTP close for ['127.0.0.1', 55342]
HTTP response complete for ['127.0.0.1', 55342]
127.0.0.1:55342 - - [04/Jan/2025:18:48:44] "POST /api/diagnosis/add/" 500 61 @api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_diagnosis(request):
    try:
        doctor = request.user.doctor
        patient_id = request.data.get('patient_id')
        diagnosis_description = request.data.get('diagnosis_description')
        appointment_id = request.data.get('appointment_id')  # Updated field
        appointment_time = request.data.get('appointment_time')
        prescription = request.FILES.get('prescription')
        digital_prescription = request.FILES.get('digital_prescription')

        # Validate required fields
        if not all([patient_id, diagnosis_description, appointment_id, appointment_time, prescription]):
            return Response({'error': 'Missing required fields'}, status=status.HTTP_400_BAD_REQUEST)

        patient = Patient.objects.get(id=patient_id)
        appointment = Appointment.objects.get(id=appointment_id)

        # Verify that the appointment belongs to the patient and doctor
        if appointment.patient != patient or appointment.doctor != doctor:
            return Response({'error': 'Invalid appointment for the given patient and doctor'}, status=status.HTTP_400_BAD_REQUEST)

        # Create the diagnosis using serializer
        diagnosis_data = {
            'patient': patient,
            'doctor': doctor,
            'appointment': appointment.id,  # Include appointment
            'diagnosis_description': diagnosis_description,
            'appointment_time': appointment_time,
            'prescription': prescription,
            'digital_prescription': digital_prescription
        }
        diagnosis_serializer = DiagnosisSerializer(data=diagnosis_data)
        if diagnosis_serializer.is_valid():
            diagnosis = diagnosis_serializer.save()

            # Add to medical history using serializer
            medical_history_data = {
                'patient': patient.id,
                'description': f"Diagnosis by Dr. {doctor.user.username}: {diagnosis_description}",
                'category': 'diagnosis',
                'updated_by': doctor.user.id
            }
            medical_history_serializer = MedicalHistorySerializer(data=medical_history_data)
            if medical_history_serializer.is_valid():
                medical_history_serializer.save()

            return Response({
                'message': 'Diagnosis added successfully',
                'diagnosis_id': diagnosis.id
            }, status=status.HTTP_201_CREATED)
        else:
            return Response(diagnosis_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    except Patient.DoesNotExist:
        return Response({'error': 'Patient not found'}, status=status.HTTP_404_NOT_FOUND)
    except Appointment.DoesNotExist:
        return Response({'error': 'Appointment not found'}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name', 'password']
        extra_kwargs = {
            'password': {'write_only': True}
        }

    def create(self, validated_data):
        password = validated_data.pop('password', None)
        user = User(**validated_data)
        user.is_active = False
        if password is not None:
            user.set_password(password)
        user.save()
        return user

    def update(self, instance, validated_data):
        password = validated_data.pop('password', None)
        if password:
            instance.set_password(password)
        return super().update(instance, validated_data)


class MedicalReportSerializer(serializers.ModelSerializer):
    # Added `id` field
    class Meta:
        model = MedicalReport
        fields = ['id', 'file', 'uploaded_at']


class MedicalHistorySerializer(serializers.ModelSerializer):
    updated_by = serializers.StringRelatedField()

    class Meta:
        model = MedicalHistory
        fields = ['id', 'patient', 'description', 'category', 'created_at', 'updated_at', 'updated_by']
        read_only_fields = ['created_at', 'updated_at', 'updated_by']


class VitalSerializer(serializers.ModelSerializer):
    class Meta:
        model = Vital
        fields = ['id', 'patient', 'date_recorded', 'blood_pressure', 'pulse_rate', 'oxygen_level', 'weight', 'height', 'bmi']
        read_only_fields = ['id', 'patient', 'date_recorded', 'bmi']

    def validate(self, data):
        weight = data.get('weight')
        height = data.get('height')
        if weight is not None and height is not None:
            height_in_meters = height / 100.0
            data['bmi'] = weight / (height_in_meters ** 2)
        return data







class PatientSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    medical_reports = MedicalReportSerializer(many=True, read_only=True)
    medical_histories = MedicalHistorySerializer(many=True, read_only=True)
    vitals = VitalSerializer(many=True, read_only=True)

    class Meta:
        model = Patient
        fields = ['id', 'user', 'country', 'phone', 'dob', 'gender', 'medical_reports', 'medical_histories', 'vitals']

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user = User.objects.create_user(**user_data, is_active=False)
        patient = Patient.objects.create(user=user, **validated_data)
        medical_reports_data = self.context.get('medical_reports', [])
        for report_data in medical_reports_data:
            report = MedicalReport.objects.create(**report_data)
            patient.medical_reports.add(report)
        return patient





class DoctorSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    class Meta:
        model = Doctor
        fields = ['id','user', 'country', 'phone', 'degree', 'specialization', 'years_of_experience', 'branch', 'profile_photo', 'user_type']
        extra_kwargs = {
            'specialization': {'required': False}  # specialization is not required now
        }

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user = User.objects.create_user(**user_data)
        doctor = Doctor.objects.create(user=user, user_type='doctor', **validated_data)
        return doctor
    
    
# 4. DiagnosisSerializer
class DiagnosisSerializer(serializers.ModelSerializer):
    doctor = DoctorSerializer(read_only=True)
    patient = PatientSerializer(read_only=True)
    appointment = serializers.PrimaryKeyRelatedField(queryset=Appointment.objects.all())

    class Meta:
        model = Diagnosis
        fields = [
            'id',
            'patient',
            'doctor',
            'appointment',
            'diagnosis_description',
            'appointment_time',
            'prescription',
            'digital_prescription',
            'created_at'
        ]
        read_only_fields = ['created_at']  

class PatientSimpleSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Patient
        fields = ['id', 'user','country', 'dob', 'gender','phone']

class AppointmentSerializer(serializers.ModelSerializer):
    doctor = serializers.PrimaryKeyRelatedField(
        queryset=Doctor.objects.all(),
        required=False,
        allow_null=True
    )
    patient = PatientSimpleSerializer(read_only=True)
    appointment_time = serializers.DateTimeField(required=False)
    diagnoses = DiagnosisSerializer(many=True, read_only=True)  # Add this line

    class Meta:
        model = Appointment
        fields = [
            'id', 'doctor', 'patient', 'problem_description',
            'problem_heading', 'appointment_time', 'status', 'diagnoses'
        ]
        extra_kwargs = {
            'appointment_time': {'required': False},
        }

    def to_representation(self, instance):
        ret = super().to_representation(instance)
        doctor = instance.doctor
        if doctor:
            request = self.context.get('request', None)
            profile_photo_url = None
            if doctor.profile_photo and hasattr(doctor.profile_photo, 'url'):
                profile_photo_url = (request.build_absolute_uri(doctor.profile_photo.url) 
                                    if request else doctor.profile_photo.url)
            # Include the doctor.id here
            ret['doctor'] = {
                'id': doctor.id,  # The primary key of the Doctor model
                'user': {
                    'id': doctor.user.id,
                    'username': doctor.user.username,
                    'first_name': doctor.user.first_name,
                    'last_name': doctor.user.last_name
                },
                'country': doctor.country,
                'degree': doctor.degree,
                'specialization': doctor.specialization,
                'years_of_experience': doctor.years_of_experience,
                'branch': doctor.branch,
                'profile_photo': profile_photo_url,
                'user_type': doctor.user_type
            }
        else:
            ret['doctor'] = None
        return ret