""" Organizations serializers """ from rest_framework import serializers from .models import Department, Hospital, Organization, Patient, Staff class OrganizationSerializer(serializers.ModelSerializer): """Organization serializer""" hospitals_count = serializers.SerializerMethodField() class Meta: model = Organization fields = [ 'id', 'name', 'name_ar', 'code', 'address', 'city', 'phone', 'email', 'website', 'status', 'license_number', 'logo', 'hospitals_count', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] def get_hospitals_count(self, obj): """Get count of hospitals in this organization""" return obj.hospitals.count() class HospitalSerializer(serializers.ModelSerializer): """Hospital serializer""" organization_name = serializers.CharField(source='organization.name', read_only=True) departments_count = serializers.SerializerMethodField() class Meta: model = Hospital fields = [ 'id', 'organization', 'organization_name', 'name', 'name_ar', 'code', 'address', 'city', 'phone', 'email', 'status', 'license_number', 'capacity', 'departments_count', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] def get_departments_count(self, obj): """Get count of departments in this hospital""" return obj.departments.count() class DepartmentSerializer(serializers.ModelSerializer): """Department serializer""" hospital_name = serializers.CharField(source='hospital.name', read_only=True) parent_name = serializers.CharField(source='parent.name', read_only=True) manager_name = serializers.SerializerMethodField() class Meta: model = Department fields = [ 'id', 'hospital', 'hospital_name', 'name', 'name_ar', 'code', 'parent', 'parent_name', 'manager', 'manager_name', 'phone', 'email', 'location', 'status', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] def get_manager_name(self, obj): """Get manager full name""" if obj.manager: return obj.manager.get_full_name() return None class StaffSerializer(serializers.ModelSerializer): """Staff serializer""" hospital_name = serializers.CharField(source='hospital.name', read_only=True) department_name = serializers.CharField(source='department.name', read_only=True) full_name = serializers.CharField(source='get_full_name', read_only=True) user_email = serializers.EmailField(source='user.email', read_only=True, allow_null=True) has_user_account = serializers.BooleanField(read_only=True) # User creation fields (write-only) create_user = serializers.BooleanField(write_only=True, required=False, default=False) user_username = serializers.CharField(write_only=True, required=False, allow_blank=True) user_password = serializers.CharField(write_only=True, required=False, allow_blank=True) send_email = serializers.BooleanField(write_only=True, required=False, default=True) class Meta: model = Staff fields = [ 'id', 'user', 'first_name', 'last_name', 'first_name_ar', 'last_name_ar', 'full_name', 'staff_type', 'job_title', 'license_number', 'specialization', 'employee_id', 'hospital', 'hospital_name', 'department', 'department_name', 'user_email', 'has_user_account', 'status', 'created_at', 'updated_at', 'create_user', 'user_username', 'user_password', 'send_email' ] read_only_fields = ['id', 'created_at', 'updated_at'] def to_representation(self, instance): """Customize representation""" data = super().to_representation(instance) data['has_user_account'] = instance.user is not None return data def create(self, validated_data): """Create staff with optional user account""" # Extract user creation fields create_user = validated_data.pop('create_user', False) user_username = validated_data.pop('user_username', '') user_password = validated_data.pop('user_password', '') send_email = validated_data.pop('send_email', True) # Create staff instance staff = Staff.objects.create(**validated_data) # Optionally create user account if create_user and not staff.user: from .services import StaffService # Determine role based on staff_type role = StaffService.get_staff_type_role(staff.staff_type) # Create user account try: user, password = StaffService.create_user_for_staff( staff, role=role, request=self.context.get('request') ) # Send email if requested if send_email and self.context.get('request'): try: StaffService.send_credentials_email( staff, password, self.context['request'] ) except Exception as e: # Log but don't fail if email sending fails pass except ValueError as e: # If user creation fails, still return the staff pass return staff def update(self, instance, validated_data): """Update staff with optional user account creation""" # Extract user creation fields create_user = validated_data.pop('create_user', False) user_username = validated_data.pop('user_username', '') user_password = validated_data.pop('user_password', '') send_email = validated_data.pop('send_email', True) # Update staff fields for attr, value in validated_data.items(): setattr(instance, value) instance.save() # Optionally create user account if it doesn't exist if create_user and not instance.user: from .services import StaffService # Determine role based on staff_type role = StaffService.get_staff_type_role(instance.staff_type) try: user, password = StaffService.create_user_for_staff( instance, role=role, request=self.context.get('request') ) # Send email if requested if send_email and self.context.get('request'): try: StaffService.send_credentials_email( instance, password, self.context['request'] ) except Exception as e: pass except ValueError as e: pass return instance class PatientSerializer(serializers.ModelSerializer): """Patient serializer""" primary_hospital_name = serializers.CharField(source='primary_hospital.name', read_only=True) full_name = serializers.CharField(source='get_full_name', read_only=True) age = serializers.SerializerMethodField() class Meta: model = Patient fields = [ 'id', 'mrn', 'national_id', 'first_name', 'last_name', 'first_name_ar', 'last_name_ar', 'full_name', 'date_of_birth', 'age', 'gender', 'phone', 'email', 'address', 'city', 'primary_hospital', 'primary_hospital_name', 'status', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] def get_age(self, obj): """Calculate patient age""" if obj.date_of_birth: from datetime import date today = date.today() return today.year - obj.date_of_birth.year - ( (today.month, today.day) < (obj.date_of_birth.month, obj.date_of_birth.day) ) return None class PatientListSerializer(serializers.ModelSerializer): """Simplified patient serializer for list views""" full_name = serializers.CharField(source='get_full_name', read_only=True) primary_hospital_name = serializers.CharField(source='primary_hospital.name', read_only=True) class Meta: model = Patient fields = [ 'id', 'mrn', 'full_name', 'phone', 'email', 'primary_hospital_name', 'status' ]