HH/apps/organizations/models.py
2026-01-01 16:44:42 +03:00

230 lines
6.7 KiB
Python

"""
Organizations models - Hospital, Department, Physician, Employee, Patient
"""
from django.db import models
from apps.core.models import TimeStampedModel, UUIDModel, StatusChoices
class Hospital(UUIDModel, TimeStampedModel):
"""Hospital/Facility model"""
name = models.CharField(max_length=200)
name_ar = models.CharField(max_length=200, blank=True, verbose_name="Name (Arabic)")
code = models.CharField(max_length=50, unique=True, db_index=True)
# Contact information
address = models.TextField(blank=True)
city = models.CharField(max_length=100, blank=True)
phone = models.CharField(max_length=20, blank=True)
email = models.EmailField(blank=True)
# Status
status = models.CharField(
max_length=20,
choices=StatusChoices.choices,
default=StatusChoices.ACTIVE,
db_index=True
)
# Metadata
license_number = models.CharField(max_length=100, blank=True)
capacity = models.IntegerField(null=True, blank=True, help_text="Bed capacity")
metadata = models.JSONField(default=dict, blank=True)
class Meta:
ordering = ['name']
verbose_name_plural = 'Hospitals'
def __str__(self):
return self.name
class Department(UUIDModel, TimeStampedModel):
"""Department within a hospital"""
hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, related_name='departments')
name = models.CharField(max_length=200)
name_ar = models.CharField(max_length=200, blank=True, verbose_name="Name (Arabic)")
code = models.CharField(max_length=50, db_index=True)
# Hierarchy
parent = models.ForeignKey(
'self',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='sub_departments'
)
# Manager
manager = models.ForeignKey(
'accounts.User',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='managed_departments'
)
# Contact
phone = models.CharField(max_length=20, blank=True)
email = models.EmailField(blank=True)
location = models.CharField(max_length=200, blank=True, help_text="Building/Floor/Room")
# Status
status = models.CharField(
max_length=20,
choices=StatusChoices.choices,
default=StatusChoices.ACTIVE,
db_index=True
)
class Meta:
ordering = ['hospital', 'name']
unique_together = [['hospital', 'code']]
def __str__(self):
return f"{self.hospital.name} - {self.name}"
# TODO Add Section
class Physician(UUIDModel, TimeStampedModel):
"""Physician/Doctor model"""
# Link to user account (optional - some physicians may not have system access)
user = models.OneToOneField(
'accounts.User',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='physician_profile'
)
# Basic information
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
first_name_ar = models.CharField(max_length=100, blank=True)
last_name_ar = models.CharField(max_length=100, blank=True)
# Professional information
license_number = models.CharField(max_length=100, unique=True, db_index=True)
specialization = models.CharField(max_length=200)
# Organization
hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, related_name='physicians')
department = models.ForeignKey(
Department,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='physicians'
)
# Contact
phone = models.CharField(max_length=20, blank=True)
email = models.EmailField(blank=True)
# Status
status = models.CharField(
max_length=20,
choices=StatusChoices.choices,
default=StatusChoices.ACTIVE,
db_index=True
)
class Meta:
ordering = ['last_name', 'first_name']
def __str__(self):
return f"Dr. {self.first_name} {self.last_name}"
def get_full_name(self):
return f"{self.first_name} {self.last_name}"
class Employee(UUIDModel, TimeStampedModel):
"""Employee model (non-physician staff)"""
user = models.OneToOneField(
'accounts.User',
on_delete=models.CASCADE,
related_name='employee_profile'
)
# Organization
hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, related_name='employees')
department = models.ForeignKey(
Department,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='employees'
)
# Job information
employee_id = models.CharField(max_length=50, unique=True, db_index=True)
job_title = models.CharField(max_length=200)
hire_date = models.DateField(null=True, blank=True)
# Status
status = models.CharField(
max_length=20,
choices=StatusChoices.choices,
default=StatusChoices.ACTIVE,
db_index=True
)
class Meta:
ordering = ['user__last_name', 'user__first_name']
def __str__(self):
return f"{self.user.get_full_name()} - {self.job_title}"
class Patient(UUIDModel, TimeStampedModel):
"""Patient model"""
# Basic information
mrn = models.CharField(max_length=50, unique=True, db_index=True, verbose_name="Medical Record Number")
national_id = models.CharField(max_length=50, blank=True, db_index=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
first_name_ar = models.CharField(max_length=100, blank=True)
last_name_ar = models.CharField(max_length=100, blank=True)
# Demographics
date_of_birth = models.DateField(null=True, blank=True)
gender = models.CharField(
max_length=10,
choices=[('male', 'Male'), ('female', 'Female'), ('other', 'Other')],
blank=True
)
# Contact
phone = models.CharField(max_length=20, blank=True)
email = models.EmailField(blank=True)
address = models.TextField(blank=True)
city = models.CharField(max_length=100, blank=True)
# Primary hospital
primary_hospital = models.ForeignKey(
Hospital,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='patients'
)
# Status
status = models.CharField(
max_length=20,
choices=StatusChoices.choices,
default=StatusChoices.ACTIVE,
db_index=True
)
class Meta:
ordering = ['last_name', 'first_name']
def __str__(self):
return f"{self.first_name} {self.last_name} (MRN: {self.mrn})"
def get_full_name(self):
return f"{self.first_name} {self.last_name}"