hospital-management/patients_data.py
Marwan Alwali 2780a2dc7c update
2025-09-16 15:10:57 +03:00

523 lines
22 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import django
# Set up Django environment
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hospital_management.settings')
django.setup()
import uuid
import random
from datetime import datetime, timedelta, date
from django.utils import timezone as django_timezone
from django.contrib.auth import get_user_model
from core.models import Tenant
from patients.models import (
PatientProfile, EmergencyContact, InsuranceInfo,
ConsentTemplate, ConsentForm, PatientNote
)
User = get_user_model()
# Saudi-inspired names and data
SAUDI_FIRST_NAMES_MALE = [
'Abdullah', 'Mohammed', 'Ahmad', 'Ali', 'Omar', 'Khalid', 'Fahd', 'Sultan',
'Faisal', 'Saud', 'Abdulrahman', 'Abdulaziz', 'Turki', 'Bandar', 'Nasser',
'Saad', 'Majed', 'Waleed', 'Yousef', 'Ibrahim', 'Hassan', 'Hussein'
]
SAUDI_FIRST_NAMES_FEMALE = [
'Fatima', 'Aisha', 'Khadija', 'Maryam', 'Nora', 'Sarah', 'Hala', 'Reem',
'Layla', 'Amina', 'Zahra', 'Lina', 'Nada', 'Rana', 'Dina', 'Hind',
'Najla', 'Arwa', 'Ghada', 'Nouf', 'Abeer', 'Thuraya', 'Wafa', 'Lama'
]
SAUDI_FAMILY_NAMES = [
'Al-Saud', 'Al-Rashid', 'Al-Mutairi', 'Al-Otaibi', 'Al-Qarni', 'Al-Harbi',
'Al-Dawsari', 'Al-Subai', 'Al-Sharani', 'Al-Ghamdi', 'Al-Zahrani', 'Al-Maliki',
'Al-Shehri', 'Al-Qahtani', 'Al-Ansari', 'Al-Hakim', 'Al-Rashidi', 'Al-Bakr'
]
SAUDI_CITIES = [
'Riyadh', 'Jeddah', 'Mecca', 'Medina', 'Dammam', 'Khobar', 'Dhahran',
'Taif', 'Tabuk', 'Buraidah', 'Khamis Mushait', 'Hail', 'Najran'
]
SAUDI_STATES = [
'Riyadh Province', 'Makkah Province', 'Eastern Province', 'Asir Province',
'Jazan Province', 'Madinah Province', 'Qassim Province', 'Tabuk Province'
]
SAUDI_LANGUAGES = ['Arabic', 'English']
SAUDI_ALLERGIES = [
'Penicillin', 'Aspirin', 'Ibuprofen', 'Sulfa drugs', 'Contrast dye',
'Peanuts', 'Shellfish', 'Dairy', 'Eggs', 'Tree nuts', 'Latex'
]
SAUDI_INSURANCE_COMPANIES = [
'Saudi Enaya Cooperative Insurance', 'Bupa Arabia', 'Tawuniya',
'Malath Insurance', 'Walaa Insurance', 'Gulf Union Alahlia Insurance'
]
SAUDI_CONSENT_CATEGORIES = [
'TREATMENT', 'PROCEDURE', 'SURGERY', 'ANESTHESIA', 'RESEARCH'
]
def generate_saudi_phone():
"""Generate Saudi phone number"""
return f"+966{random.randint(11, 17)}{random.randint(1000000, 9999999)}"
def generate_saudi_mobile():
"""Generate Saudi mobile number"""
return f"+966{random.randint(50, 59)}{random.randint(1000000, 9999999)}"
def generate_saudi_medical_record_number():
"""Generate medical record number"""
return f"MRN{random.randint(100000, 999999)}"
def create_saudi_patient_profiles():
"""Create Saudi patient profiles using only valid model fields"""
print("Creating Saudi patient profiles...")
tenants = list(Tenant.objects.all())
if not tenants:
print("No tenants found. Please create tenants first.")
return []
profiles_created = 0
created_profiles = []
for i in range(50): # Start with 50 patients
try:
tenant = random.choice(tenants)
gender = random.choice(['MALE', 'FEMALE'])
if gender == 'MALE':
first_name = random.choice(SAUDI_FIRST_NAMES_MALE)
else:
first_name = random.choice(SAUDI_FIRST_NAMES_FEMALE)
last_name = random.choice(SAUDI_FAMILY_NAMES)
# Generate birth date (18-85 years old)
birth_year = random.randint(1939, 2006)
birth_month = random.randint(1, 12)
birth_day = random.randint(1, 28)
date_of_birth = date(birth_year, birth_month, birth_day)
# Generate unique MRN
mrn = random.randint(100000, 999999)
# Check if MRN already exists
while PatientProfile.objects.filter(mrn=mrn).exists():
mrn = f"MRN{tenant.id}{random.randint(100000, 999999)}"
# Only use fields that actually exist in the model
profile = PatientProfile.objects.create(
tenant=tenant,
mrn=mrn,
first_name=first_name,
last_name=last_name,
middle_name=random.choice(SAUDI_FIRST_NAMES_MALE + SAUDI_FIRST_NAMES_FEMALE) if random.choice(
[True, False]) else None,
preferred_name=first_name if random.choice([True, False]) else None,
suffix=random.choice([None, 'Jr.', 'Sr.']) if random.random() < 0.05 else None,
date_of_birth=date_of_birth,
gender=gender,
# Contact Information
email=f"{first_name.lower()}.{last_name.lower().replace('-', '').replace(' ', '')}@email.com" if random.choice(
[True, False]) else None,
phone_number=generate_saudi_phone() if random.choice([True, False]) else None,
mobile_number=generate_saudi_mobile(),
# Address - using correct field names from model
address_line_1=f"{random.randint(1, 999)} {random.choice(['King Fahd Road', 'Prince Sultan Street', 'Al Malik Road'])}",
address_line_2=f"Apt {random.randint(1, 50)}" if random.choice([True, False]) else None,
city=random.choice(SAUDI_CITIES),
state=random.choice(SAUDI_STATES),
zip_code=f"{random.randint(10000, 99999)}",
country='Saudi Arabia',
# Demographics
marital_status=random.choice(['SINGLE', 'MARRIED', 'DIVORCED', 'WIDOWED']),
occupation=random.choice([
'Engineer', 'Teacher', 'Doctor', 'Nurse', 'Government Employee',
'Business Owner', 'Student', 'Retired', 'Homemaker'
]) if random.choice([True, False]) else None,
employer=random.choice([
'Saudi Aramco', 'SABIC', 'Ministry of Health', 'King Saud University',
'Saudi Telecom Company', 'Al Rajhi Bank'
]) if random.choice([True, False]) else None,
# Language and Communication
primary_language=random.choice(SAUDI_LANGUAGES),
interpreter_needed=random.choice([True, False]) if random.random() < 0.1 else False,
communication_preference=random.choice(['PHONE', 'EMAIL', 'SMS', 'MAIL']),
# Healthcare Information
primary_care_physician=f"Dr. {random.choice(SAUDI_FIRST_NAMES_MALE + SAUDI_FIRST_NAMES_FEMALE)} {random.choice(SAUDI_FAMILY_NAMES)}" if random.choice(
[True, False]) else None,
# Medical Information
allergies=', '.join(random.sample(SAUDI_ALLERGIES, random.randint(0, 3))) if random.choice(
[True, False]) else None,
medical_alerts=random.choice([
'Patient has diabetes - monitor blood sugar',
'Hypertension - check BP regularly',
'Patient requires wheelchair assistance',
'Arabic speaking only'
]) if random.choice([True, False]) else None,
# Advance Directives
has_advance_directive=random.choice([True, False]) if random.random() < 0.2 else False,
advance_directive_type=random.choice(['LIVING_WILL', 'HEALTHCARE_PROXY', 'DNR']) if random.choice(
[True, False]) else None,
# Status
is_active=True,
is_deceased=False,
is_vip=random.choice([True, False]) if random.random() < 0.05 else False,
confidential_patient=random.choice([True, False]) if random.random() < 0.02 else False,
# Registration date in the past
registration_date=django_timezone.now() - timedelta(days=random.randint(1, 365)),
last_visit_date=django_timezone.now() - timedelta(days=random.randint(1, 90)) if random.choice(
[True, False]) else None,
)
created_profiles.append(profile)
profiles_created += 1
if profiles_created % 10 == 0:
print(f"Created {profiles_created} patient profiles...")
except Exception as e:
print(f"Error creating patient profile {i}: {str(e)}")
continue
print(f"Successfully created {profiles_created} Saudi patient profiles.")
return created_profiles
def create_saudi_emergency_contacts(patients):
"""Create emergency contacts for patients"""
print("Creating Saudi emergency contacts...")
contacts_created = 0
for patient in patients:
# Create 1-2 emergency contacts per patient
num_contacts = random.randint(1, 2)
for i in range(num_contacts):
try:
gender = random.choice(['MALE', 'FEMALE'])
if gender == 'MALE':
first_name = random.choice(SAUDI_FIRST_NAMES_MALE)
else:
first_name = random.choice(SAUDI_FIRST_NAMES_FEMALE)
EmergencyContact.objects.create(
patient=patient,
first_name=first_name,
last_name=random.choice(SAUDI_FAMILY_NAMES),
relationship=random.choice([
'SPOUSE', 'PARENT', 'CHILD', 'SIBLING', 'FRIEND', 'OTHER'
]),
phone_number=generate_saudi_mobile(),
mobile_number=generate_saudi_phone() if random.choice([True, False]) else None,
email=f"{first_name.lower()}@email.com" if random.choice([True, False]) else None,
address_line_1=f"{random.randint(1, 999)} {random.choice(['King Fahd Road', 'Prince Sultan Street'])}",
city=random.choice(SAUDI_CITIES),
state=random.choice(SAUDI_STATES),
zip_code=f"{random.randint(10000, 99999)}",
priority=i + 1,
is_authorized_for_medical_decisions=i == 0,
is_authorized_for_information=True,
notes=random.choice([
'Available during business hours',
'Contact only in emergencies',
'Primary caregiver'
]) if random.choice([True, False]) else None,
)
contacts_created += 1
except Exception as e:
print(f"Error creating emergency contact for patient {patient.mrn}: {str(e)}")
continue
print(f"Successfully created {contacts_created} emergency contacts.")
return contacts_created
def create_saudi_insurance_info(patients):
"""Create insurance information for patients"""
print("Creating Saudi insurance information...")
insurance_created = 0
for patient in patients:
# 80% of patients have insurance
if random.random() < 0.8:
try:
company = random.choice(SAUDI_INSURANCE_COMPANIES)
InsuranceInfo.objects.create(
patient=patient,
insurance_type=random.choice(['PRIMARY', 'SECONDARY']),
insurance_company=company,
plan_name=f"{company} Standard Plan" if random.choice([True, False]) else None,
plan_type=random.choice(['HMO', 'PPO', 'OTHER']),
policy_number=f"{company[:3].upper()}{random.randint(100000, 999999)}",
group_number=f"GRP{random.randint(1000, 9999)}" if random.choice([True, False]) else None,
subscriber_name=f"{patient.first_name} {patient.last_name}",
subscriber_relationship=random.choice(['SELF', 'SPOUSE', 'CHILD', 'PARENT']),
subscriber_dob=patient.date_of_birth if random.choice([True, False]) else None,
effective_date=date.today() - timedelta(days=random.randint(30, 730)),
termination_date=date.today() + timedelta(days=random.randint(30, 365)) if random.choice(
[True, False]) else None,
copay_amount=random.choice([50, 100, 150, 200]),
deductible_amount=random.choice([500, 1000, 2000, 3000]),
out_of_pocket_max=random.choice([5000, 7500, 10000]) if random.choice([True, False]) else None,
is_verified=random.choice([True, False]),
verification_date=django_timezone.now() - timedelta(days=random.randint(1, 30)) if random.choice(
[True, False]) else None,
)
insurance_created += 1
except Exception as e:
print(f"Error creating insurance info for patient {patient.mrn}: {str(e)}")
continue
print(f"Successfully created {insurance_created} insurance records.")
return insurance_created
def create_saudi_consent_templates():
"""Create consent form templates"""
print("Creating Saudi consent templates...")
tenants = list(Tenant.objects.all())
templates_created = 0
consent_data = [
('General Treatment Consent', 'TREATMENT', 'Standard consent for medical treatment'),
('Surgery Consent', 'SURGERY', 'Consent for surgical procedures'),
('Anesthesia Consent', 'ANESTHESIA', 'Consent for anesthesia administration'),
('Procedure Consent', 'PROCEDURE', 'Consent for medical procedures'),
('Research Consent', 'RESEARCH', 'Consent for research participation'),
]
for tenant in tenants:
for name, category, description in consent_data:
try:
ConsentTemplate.objects.create(
tenant=tenant,
name=name,
description=description,
category=category,
content=f"""
CONSENT FOR {name.upper()}
I, the undersigned patient, acknowledge that I have been informed about the nature of the proposed {name.lower()}.
I understand that:
1. The procedure/treatment has been explained to me
2. Alternative treatments have been discussed
3. Risks and benefits have been explained
4. I have had the opportunity to ask questions
I hereby give my informed consent.
Patient Signature: _____________________ Date: ___________
""".strip(),
version='1.0',
is_active=True,
requires_signature=True,
requires_witness=random.choice([True, False]),
requires_guardian=random.choice([True, False]),
effective_date=django_timezone.now().date(),
expiry_date=django_timezone.now().date() + timedelta(days=365) if random.choice(
[True, False]) else None,
)
templates_created += 1
except Exception as e:
print(f"Error creating consent template '{name}' for tenant {tenant.name}: {str(e)}")
continue
print(f"Successfully created {templates_created} consent templates.")
return templates_created
def create_saudi_consent_forms(patients, templates):
"""Create completed consent forms for patients"""
print("Creating Saudi consent forms...")
users = list(User.objects.filter(is_active=True))
forms_created = 0
for patient in patients:
# Each patient has 1-2 consent forms
num_forms = random.randint(1, 2)
patient_templates = [t for t in templates if t.tenant == patient.tenant]
if not patient_templates:
continue
selected_templates = random.sample(patient_templates, min(num_forms, len(patient_templates)))
for template in selected_templates:
try:
signed_datetime = django_timezone.now() - timedelta(days=random.randint(1, 180))
ConsentForm.objects.create(
patient=patient,
template=template,
status='SIGNED', # Use the correct field name from model
patient_signature=f"Digital signature by {patient.get_full_name()}",
patient_signed_at=signed_datetime, # Use the correct field name
guardian_signature=f"Guardian signature for {patient.get_full_name()}" if template.requires_guardian and patient.age and patient.age < 18 else None,
guardian_signed_at=signed_datetime if template.requires_guardian and patient.age and patient.age < 18 else None,
guardian_name=f"{random.choice(SAUDI_FIRST_NAMES_MALE + SAUDI_FIRST_NAMES_FEMALE)} {random.choice(SAUDI_FAMILY_NAMES)}" if template.requires_guardian and patient.age and patient.age < 18 else None,
guardian_relationship=random.choice(['PARENT',
'GUARDIAN']) if template.requires_guardian and patient.age and patient.age < 18 else None,
witness_signature=f"Witness signature" if template.requires_witness else None,
witness_signed_at=signed_datetime if template.requires_witness else None, # Use correct field name
witness_name=f"{random.choice(SAUDI_FIRST_NAMES_MALE + SAUDI_FIRST_NAMES_FEMALE)} {random.choice(SAUDI_FAMILY_NAMES)}" if template.requires_witness else None,
witness_title=random.choice(
['Nurse', 'Administrator', 'Staff']) if template.requires_witness else None,
provider_name=f"Dr. {random.choice(SAUDI_FIRST_NAMES_MALE + SAUDI_FIRST_NAMES_FEMALE)} {random.choice(SAUDI_FAMILY_NAMES)}" if random.choice(
[True, False]) else None,
effective_date=signed_datetime,
expiry_date=signed_datetime + timedelta(days=365) if template.expiry_date else None,
created_by=random.choice(users) if users and random.choice([True, False]) else None,
notes=random.choice([
'Patient fully understood the procedure',
'All questions answered satisfactorily',
'Consent obtained in Arabic',
'Interpreter services provided'
]) if random.choice([True, False]) else None,
)
forms_created += 1
except Exception as e:
print(f"Error creating consent form for patient {patient.mrn}: {str(e)}")
continue
print(f"Successfully created {forms_created} consent forms.")
return forms_created
def create_saudi_patient_notes(patients):
"""Create patient notes"""
print("Creating Saudi patient notes...")
users = list(User.objects.filter(is_active=True))
notes_created = 0
note_data = [
('Routine Check-up', 'Patient presents for routine examination. Vital signs stable.', 'CLINICAL'),
('Insurance Verification', 'Insurance information verified and updated.', 'ADMINISTRATIVE'),
('Follow-up Required', 'Patient requires follow-up in 2 weeks.', 'CLINICAL'),
('Billing Note', 'Updated billing information and payment plan.', 'BILLING'),
('Medication Review', 'Reviewed current medications with patient.', 'CLINICAL'),
('Contact Update', 'Updated emergency contact information.', 'ADMINISTRATIVE'),
]
for patient in patients:
# Each patient has 2-4 notes
num_notes = random.randint(2, 4)
for i in range(num_notes):
try:
title, content, category = random.choice(note_data)
PatientNote.objects.create(
patient=patient,
title=title,
content=content,
category=category,
priority=random.choice(['LOW', 'NORMAL', 'HIGH']),
is_confidential=random.choice([True, False]),
is_alert=random.choice([True, False]) if random.random() < 0.1 else False,
created_by=random.choice(users) if users else None,
created_at=django_timezone.now() - timedelta(days=random.randint(1, 365)),
)
notes_created += 1
except Exception as e:
print(f"Error creating note for patient {patient.mrn}: {str(e)}")
continue
print(f"Successfully created {notes_created} patient notes.")
return notes_created
def main():
"""Main function to create all Saudi patient data"""
print("🏥 Creating Saudi Patient Data")
try:
# Check if tenants exist
tenants = list(Tenant.objects.all())
if not tenants:
print("❌ No tenants found. Please run core_data.py first.")
return
print(f"📋 Found {len(tenants)} tenants")
# Create patient profiles first
print("\n1⃣ Creating Patient Profiles...")
patients = create_saudi_patient_profiles()
if not patients:
print("❌ No patients created. Stopping.")
return
# Create emergency contacts
print("\n2⃣ Creating Emergency Contacts...")
contacts_count = create_saudi_emergency_contacts(patients)
# Create insurance info
print("\n3⃣ Creating Insurance Information...")
insurance_count = create_saudi_insurance_info(patients)
# Create consent templates
print("\n4⃣ Creating Consent Templates...")
templates_count = create_saudi_consent_templates()
templates = list(ConsentTemplate.objects.all())
# Create consent forms
print("\n5⃣ Creating Consent Forms...")
forms_count = create_saudi_consent_forms(patients, templates)
# Create patient notes
print("\n6⃣ Creating Patient Notes...")
notes_count = create_saudi_patient_notes(patients)
print("\n🎉 Saudi Patient Data Creation Complete!")
print(f"📊 Summary:")
print(f" - Patient Profiles: {len(patients)}")
print(f" - Emergency Contacts: {contacts_count}")
print(f" - Insurance Records: {insurance_count}")
print(f" - Consent Templates: {templates_count}")
print(f" - Consent Forms: {forms_count}")
print(f" - Patient Notes: {notes_count}")
except Exception as e:
print(f"❌ Error in main execution: {str(e)}")
if __name__ == '__main__':
main()