agdar/core/serializers.py
2025-11-02 14:35:35 +03:00

197 lines
6.8 KiB
Python

"""
DRF Serializers for Core app.
"""
from rest_framework import serializers
from django.contrib.auth import get_user_model
from .models import Patient, Clinic, File, SubFile, Consent, Attachment, AuditLog
User = get_user_model()
class UserSerializer(serializers.ModelSerializer):
"""Serializer for User model."""
full_name = serializers.CharField(source='get_full_name', read_only=True)
role_display = serializers.CharField(source='get_role_display', read_only=True)
class Meta:
model = User
fields = [
'id', 'username', 'email', 'first_name', 'last_name', 'full_name',
'role', 'role_display', 'phone', 'is_active', 'date_joined'
]
read_only_fields = ['id', 'date_joined']
class PatientListSerializer(serializers.ModelSerializer):
"""Lightweight serializer for patient lists."""
full_name = serializers.CharField(source='get_full_name', read_only=True)
age = serializers.IntegerField(source='get_age', read_only=True)
class Meta:
model = Patient
fields = [
'id', 'mrn', 'first_name_en', 'last_name_en',
'full_name', 'date_of_birth', 'age', 'gender',
'phone', 'is_active'
]
read_only_fields = ['id', 'mrn']
class PatientDetailSerializer(serializers.ModelSerializer):
"""Detailed serializer for patient detail views."""
full_name = serializers.CharField(source='get_full_name', read_only=True)
age = serializers.IntegerField(source='get_age', read_only=True)
tenant_name = serializers.CharField(source='tenant.name', read_only=True)
class Meta:
model = Patient
fields = [
'id', 'tenant', 'tenant_name', 'mrn',
'first_name_en', 'middle_name_en', 'last_name_en',
'first_name_ar', 'middle_name_ar', 'last_name_ar',
'full_name', 'date_of_birth', 'age', 'gender',
'nationality', 'national_id', 'passport_number',
'phone', 'email', 'address',
'caregiver_name', 'caregiver_relationship', 'caregiver_phone',
'emergency_contact_name', 'emergency_contact_phone',
'is_active', 'notes',
'created_at', 'updated_at'
]
read_only_fields = ['id', 'mrn', 'created_at', 'updated_at']
class PatientCreateUpdateSerializer(serializers.ModelSerializer):
"""Serializer for creating/updating patients."""
class Meta:
model = Patient
fields = [
'first_name_en', 'middle_name_en', 'last_name_en',
'first_name_ar', 'middle_name_ar', 'last_name_ar',
'date_of_birth', 'gender', 'nationality',
'national_id', 'passport_number',
'phone', 'email', 'address',
'caregiver_name', 'caregiver_relationship', 'caregiver_phone',
'emergency_contact_name', 'emergency_contact_phone',
'notes'
]
def validate(self, data):
"""Validate patient data."""
# Ensure at least one name is provided
if not data.get('first_name_en') and not data.get('first_name_ar'):
raise serializers.ValidationError(
"At least one name (English or Arabic) must be provided."
)
return data
class ClinicSerializer(serializers.ModelSerializer):
"""Serializer for Clinic model."""
specialty_display = serializers.CharField(source='get_specialty_display', read_only=True)
class Meta:
model = Clinic
fields = [
'id', 'name_en', 'name_ar', 'specialty', 'specialty_display',
'description', 'is_active'
]
read_only_fields = ['id']
class FileSerializer(serializers.ModelSerializer):
"""Serializer for File model."""
patient_name = serializers.CharField(source='patient.get_full_name', read_only=True)
class Meta:
model = File
fields = [
'id', 'patient', 'patient_name', 'file_number',
'opened_date', 'is_active', 'notes',
'created_at', 'updated_at'
]
read_only_fields = ['id', 'file_number', 'created_at', 'updated_at']
class SubFileSerializer(serializers.ModelSerializer):
"""Serializer for SubFile model."""
patient_name = serializers.CharField(source='file.patient.get_full_name', read_only=True)
clinic_name = serializers.CharField(source='clinic.name_en', read_only=True)
class Meta:
model = SubFile
fields = [
'id', 'file', 'patient_name', 'clinic', 'clinic_name',
'subfile_number', 'opened_date', 'is_active',
'created_at', 'updated_at'
]
read_only_fields = ['id', 'subfile_number', 'created_at', 'updated_at']
class ConsentSerializer(serializers.ModelSerializer):
"""Serializer for Consent model."""
patient_name = serializers.CharField(source='patient.get_full_name', read_only=True)
consent_type_display = serializers.CharField(source='get_consent_type_display', read_only=True)
signed_by_name = serializers.CharField(source='signed_by.get_full_name', read_only=True)
class Meta:
model = Consent
fields = [
'id', 'patient', 'patient_name', 'consent_type', 'consent_type_display',
'consent_text', 'signature_data', 'signed_by', 'signed_by_name',
'signed_at', 'is_valid', 'notes',
'created_at'
]
read_only_fields = ['id', 'created_at']
class AttachmentSerializer(serializers.ModelSerializer):
"""Serializer for Attachment model."""
uploaded_by_name = serializers.CharField(source='uploaded_by.get_full_name', read_only=True)
file_size_display = serializers.SerializerMethodField()
class Meta:
model = Attachment
fields = [
'id', 'file', 'title', 'description', 'category',
'uploaded_by', 'uploaded_by_name', 'uploaded_at',
'file_size_display'
]
read_only_fields = ['id', 'uploaded_at']
def get_file_size_display(self, obj):
"""Return human-readable file size."""
if obj.file:
size = obj.file.size
for unit in ['B', 'KB', 'MB', 'GB']:
if size < 1024.0:
return f"{size:.1f} {unit}"
size /= 1024.0
return "0 B"
class AuditLogSerializer(serializers.ModelSerializer):
"""Serializer for AuditLog model."""
user_name = serializers.CharField(source='user.get_full_name', read_only=True)
action_display = serializers.CharField(source='get_action_display', read_only=True)
class Meta:
model = AuditLog
fields = [
'id', 'user', 'user_name', 'action', 'action_display',
'model_name', 'object_id', 'object_repr',
'changes', 'ip_address', 'user_agent',
'timestamp'
]
read_only_fields = ['id', 'timestamp']