247 lines
9.6 KiB
Python
247 lines
9.6 KiB
Python
"""
|
|
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_display = serializers.CharField(source='department.name', read_only=True)
|
|
department_name = serializers.CharField(read_only=True)
|
|
full_name = serializers.CharField(source='get_full_name', read_only=True)
|
|
org_info = serializers.CharField(source='get_org_info', read_only=True)
|
|
user_email = serializers.EmailField(source='user.email', read_only=True, allow_null=True)
|
|
has_user_account = serializers.BooleanField(read_only=True)
|
|
report_to_name = serializers.SerializerMethodField()
|
|
direct_reports_count = serializers.SerializerMethodField()
|
|
|
|
# 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', 'name', 'first_name', 'last_name', 'first_name_ar', 'last_name_ar',
|
|
'full_name', 'org_info', 'staff_type', 'job_title',
|
|
'license_number', 'specialization', 'employee_id',
|
|
'email', 'phone',
|
|
'hospital', 'hospital_name', 'department', 'department_name', 'department_name_display',
|
|
'location', 'section', 'subsection', 'country', 'gender',
|
|
'report_to', 'report_to_name', 'direct_reports_count',
|
|
'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 get_report_to_name(self, obj):
|
|
"""Get manager (report_to) full name"""
|
|
if obj.report_to:
|
|
return obj.report_to.get_full_name()
|
|
return None
|
|
|
|
def get_direct_reports_count(self, obj):
|
|
"""Get count of direct reports"""
|
|
return obj.direct_reports.count()
|
|
|
|
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, was_created, password = StaffService.create_user_for_staff(
|
|
staff,
|
|
role=role,
|
|
request=self.context.get('request')
|
|
)
|
|
|
|
# Send email if requested and user was created
|
|
if was_created and password and 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, was_created, password = StaffService.create_user_for_staff(
|
|
instance,
|
|
role=role,
|
|
request=self.context.get('request')
|
|
)
|
|
|
|
# Send email if requested and user was created
|
|
if was_created and password and 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'
|
|
]
|