404 lines
13 KiB
Python
404 lines
13 KiB
Python
"""
|
|
Organizations serializers
|
|
"""
|
|
|
|
from rest_framework import serializers
|
|
|
|
from .models import Department, Hospital, Location, MainSection, Organization, Patient, Staff, SubSection
|
|
|
|
|
|
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)
|
|
localized_name = serializers.CharField(source="get_localized_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",
|
|
"localized_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):
|
|
if obj.report_to:
|
|
return obj.report_to.get_localized_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"]
|
|
|
|
|
|
class LocationSerializer(serializers.ModelSerializer):
|
|
"""Location serializer for dropdown"""
|
|
|
|
name = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Location
|
|
fields = ["id", "name"]
|
|
|
|
def get_name(self, obj):
|
|
"""Return name based on current language"""
|
|
from django.utils.translation import get_language
|
|
|
|
lang = get_language()
|
|
|
|
if lang == "ar" and obj.name_ar:
|
|
return obj.name_ar
|
|
return obj.name_en if obj.name_en else obj.name_ar
|
|
|
|
|
|
class MainSectionSerializer(serializers.ModelSerializer):
|
|
"""MainSection serializer for dropdown"""
|
|
|
|
name = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = MainSection
|
|
fields = ["id", "name"]
|
|
|
|
def get_name(self, obj):
|
|
"""Return name based on current language"""
|
|
from django.utils.translation import get_language
|
|
|
|
lang = get_language()
|
|
|
|
if lang == "ar" and obj.name_ar:
|
|
return obj.name_ar
|
|
return obj.name_en if obj.name_en else obj.name_ar
|
|
|
|
|
|
class SubSectionSerializer(serializers.ModelSerializer):
|
|
"""SubSection serializer for dropdown"""
|
|
|
|
id = serializers.IntegerField(source="internal_id", read_only=True)
|
|
name = serializers.SerializerMethodField()
|
|
location_name = serializers.SerializerMethodField()
|
|
main_section_name = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = SubSection
|
|
fields = ["id", "name", "location", "main_section", "location_name", "main_section_name"]
|
|
|
|
def get_name(self, obj):
|
|
"""Return name based on current language"""
|
|
from django.utils.translation import get_language
|
|
|
|
lang = get_language()
|
|
|
|
if lang == "ar" and obj.name_ar:
|
|
return obj.name_ar
|
|
return obj.name_en if obj.name_en else obj.name_ar
|
|
|
|
def get_location_name(self, obj):
|
|
"""Return location name based on current language"""
|
|
from django.utils.translation import get_language
|
|
|
|
lang = get_language()
|
|
|
|
if lang == "ar" and obj.location.name_ar:
|
|
return obj.location.name_ar
|
|
return obj.location.name_en if obj.location.name_en else obj.location.name_ar
|
|
|
|
def get_main_section_name(self, obj):
|
|
"""Return main section name based on current language"""
|
|
from django.utils.translation import get_language
|
|
|
|
lang = get_language()
|
|
|
|
if lang == "ar" and obj.main_section.name_ar:
|
|
return obj.main_section.name_ar
|
|
return obj.main_section.name_en if obj.main_section.name_en else obj.main_section.name_ar
|