HH/seed_standards_data.py
2026-01-15 15:02:42 +03:00

593 lines
21 KiB
Python

#!/usr/bin/env python
"""
Seed script for Standards App - Creates fake data for testing
Usage: python manage.py shell < seed_standards_data.py
Or: python seed_standards_data.py
"""
import os
import sys
import django
from datetime import date, timedelta
import random
# Setup Django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev')
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
django.setup()
from apps.organizations.models import Hospital, Department, Staff, Patient
from apps.standards.models import (
StandardSource, StandardCategory, Standard,
StandardCompliance, StandardAttachment
)
from apps.accounts.models import User, Group
# Fake data generators
ARABIC_NAMES_FIRST = [
"محمد", "أحمد", "عبدالله", "سعيد", "فهد",
"محمد", "عبدالرحمن", "خالد", "سعود",
"ناصر", "سلطان", "نايف", "بندر"
]
ARABIC_NAMES_LAST = [
"العمري", "القحطاني", "الدوسري", "السبيعي",
"الشعلان", "العتيبي", "الفريح", "الزهراني",
"الراشد", "العمير", "الحربي", "الشمري"
]
ENGLISH_NAMES_FIRST = [
"Ahmed", "Mohammed", "Abdullah", "Saud", "Khalid",
"Fahad", "Nasser", "Sultan", "Naif", "Bandar",
"Sarah", "Fatima", "Aisha", "Hana", "Layla"
]
ENGLISH_NAMES_LAST = [
"Al-Omri", "Al-Qahtani", "Al-Dossari", "Al-Subaie",
"Al-Shaalan", "Al-Otaibi", "Al-Furaih", "Al-Zahrani",
"Al-Rashed", "Al-Ameer", "Al-Harbi", "Al-Shamrari"
]
HOSPITAL_NAMES = [
{
"name": "King Faisal Specialist Hospital",
"name_ar": "مستشفى الملك فيصل التخصصي",
"code": "KFSH",
"city": "Riyadh"
},
{
"name": "King Fahad Medical City",
"name_ar": "مدينة الملك فهد الطبية",
"code": "KFMC",
"city": "Riyadh"
},
{
"name": "Prince Sultan Military Medical City",
"name_ar": "مدينة الأمير سلطان الطبية العسكرية",
"code": "PSMMC",
"city": "Riyadh"
}
]
DEPARTMENTS = [
{"name": "Emergency Department", "name_ar": "قسم الطوارئ", "code": "ED"},
{"name": "Intensive Care Unit", "name_ar": "وحدة العناية المركزة", "code": "ICU"},
{"name": "Cardiology Department", "name_ar": "قسم أمراض القلب", "code": "CARDIO"},
{"name": "Surgery Department", "name_ar": "قسم الجراحة", "code": "SURG"},
{"name": "Pediatrics Department", "name_ar": "قسم طب الأطفال", "code": "PED"},
{"name": "Radiology Department", "name_ar": "قسم الأشعة", "code": "RADIO"},
{"name": "Laboratory Department", "name_ar": "قسم المختبر", "code": "LAB"},
{"name": "Pharmacy Department", "name_ar": "قسم الصيدلية", "code": "PHARM"},
]
STANDARD_SOURCES = [
{
"name": "CBAHI",
"name_ar": "المجلس المركزي لاعتماد المؤسسات الصحية",
"code": "CBAHI",
"description": "Central Board for Accreditation of Healthcare Institutions",
"website": "https://www.cbahi.gov.sa"
},
{
"name": "MOH",
"name_ar": "وزارة الصحة",
"code": "MOH",
"description": "Ministry of Health Saudi Arabia",
"website": "https://www.moh.gov.sa"
},
{
"name": "CHI",
"name_ar": "مجلس الضمان الصحي",
"code": "CHI",
"description": "Council of Health Insurance",
"website": "https://www.chi.gov.sa"
},
{
"name": "JCI",
"name_ar": "المفوضية المشتركة",
"code": "JCI",
"description": "Joint Commission International",
"website": "https://www.jointcommissioninternational.org"
}
]
STANDARD_CATEGORIES = [
{
"name": "Patient Safety",
"name_ar": "سلامة المرضى",
"description": "Standards related to patient safety and risk management",
"order": 1
},
{
"name": "Quality Management",
"name_ar": "إدارة الجودة",
"description": "Standards for quality improvement and management",
"order": 2
},
{
"name": "Infection Control",
"name_ar": "مكافحة العدوى",
"description": "Infection prevention and control standards",
"order": 3
},
{
"name": "Emergency Management",
"name_ar": "إدارة الطوارئ",
"description": "Emergency preparedness and response standards",
"order": 4
},
{
"name": "Medication Management",
"name_ar": "إدارة الأدوية",
"description": "Safe medication use and management standards",
"order": 5
},
{
"name": "Patient Rights",
"name_ar": "حقوق المرضى",
"description": "Patient rights and education standards",
"order": 6
}
]
STANDARD_TEMPLATES = [
{
"code": "CBAHI-PS-01",
"title": "Patient Identification",
"title_ar": "تحديد هوية المريض",
"description": "The hospital identifies patients accurately and consistently across all care settings using at least two patient identifiers."
},
{
"code": "CBAHI-PS-02",
"title": "Communication of Critical Test Results",
"title_ar": "التواصل بشأن نتائج الفحوصات الحرجة",
"description": "The hospital has a process for reporting critical test results to the responsible licensed caregiver."
},
{
"code": "CBAHI-PS-03",
"title": "Medication Safety",
"title_ar": "سلامة الأدوية",
"description": "The hospital safely manages high-alert medications and looks-alike/sound-alike medications."
},
{
"code": "CBAHI-PS-04",
"title": "Prevention of Healthcare-Associated Infections",
"title_ar": "منع العدوى المرتبطة بالرعاية الصحية",
"description": "The hospital implements a comprehensive program to prevent healthcare-associated infections."
},
{
"code": "CBAHI-PS-05",
"title": "Prevention of Patient Falls",
"title_ar": "منع سقوط المرضى",
"description": "The hospital assesses patients for fall risk and implements interventions to prevent falls."
},
{
"code": "CBAHI-QM-01",
"title": "Quality Improvement Program",
"title_ar": "برنامج تحسين الجودة",
"description": "The hospital has a comprehensive quality improvement program that is integrated into daily operations."
},
{
"code": "CBAHI-QM-02",
"title": "Performance Measurement",
"title_ar": "قياس الأداء",
"description": "The hospital measures and monitors performance for key processes and outcomes."
},
{
"code": "CBAHI-IC-01",
"title": "Hand Hygiene",
"title_ar": "نظافة اليدين",
"description": "The hospital implements an effective hand hygiene program to reduce infection transmission."
},
{
"code": "CBAHI-IC-02",
"title": "Isolation Precautions",
"title_ar": "احتياطات العزل",
"description": "The hospital follows standard and transmission-based precautions to prevent spread of infections."
},
{
"code": "CBAHI-EM-01",
"title": "Emergency Preparedness Plan",
"title_ar": "خطة الاستعداد للطوارئ",
"description": "The hospital has a comprehensive emergency preparedness plan that is tested regularly."
},
{
"code": "CBAHI-MM-01",
"title": "Medication Storage",
"title_ar": "تخزين الأدوية",
"description": "The hospital stores medications securely according to manufacturer and regulatory requirements."
},
{
"code": "CBAHI-PR-01",
"title": "Patient Rights and Responsibilities",
"title_ar": "حقوق وواجبات المرضى",
"description": "The hospital informs patients about their rights and responsibilities."
},
{
"code": "CBAHI-PR-02",
"title": "Patient Education",
"title_ar": "تثقيف المرضى",
"description": "The hospital provides patient education appropriate to patient needs and understanding."
}
]
def get_or_create_hospital():
"""Get or create the first hospital for testing"""
hospital = Hospital.objects.first()
if hospital:
print(f"✓ Using existing hospital: {hospital.name}")
return hospital
# Create first hospital
hospital_data = HOSPITAL_NAMES[0]
hospital = Hospital.objects.create(
name=hospital_data["name"],
name_ar=hospital_data["name_ar"],
code=hospital_data["code"],
city=hospital_data["city"],
address=f"{hospital_data['city']}, Saudi Arabia",
phone="+966110000000",
email=f"info@{hospital_data['code'].lower()}.sa",
license_number=f"LICENSE-{hospital_data['code']}",
capacity=500,
status="active"
)
print(f"✓ Created hospital: {hospital.name}")
return hospital
def create_departments(hospital):
"""Create departments for the hospital"""
print("\n--- Creating Departments ---")
for dept_data in DEPARTMENTS:
dept, created = Department.objects.get_or_create(
hospital=hospital,
code=dept_data["code"],
defaults={
"name": dept_data["name"],
"name_ar": dept_data["name_ar"],
"location": f"Building 1, Floor {random.randint(1, 5)}",
"phone": f"+96611{random.randint(100000, 999999)}",
"email": f"{dept_data['code'].lower()}@{hospital.code.lower()}.sa",
"status": "active"
}
)
if created:
print(f" ✓ Created department: {dept.name}")
else:
print(f" - Department already exists: {dept.name}")
return Department.objects.filter(hospital=hospital, status="active")
def create_users(hospital, num_users=5):
"""Create test users"""
print("\n--- Creating Users ---")
users = []
for i in range(num_users):
first_name = ENGLISH_NAMES_FIRST[random.randint(0, len(ENGLISH_NAMES_FIRST) - 1)]
last_name = ENGLISH_NAMES_LAST[random.randint(0, len(ENGLISH_NAMES_LAST) - 1)]
username = f"{first_name.lower()}.{last_name.lower()}{i+1}"
email = f"{username}@hospital.test"
user, created = User.objects.get_or_create(
username=username,
defaults={
"email": email,
"first_name": first_name,
"last_name": last_name,
"is_active": True
}
)
if created:
user.set_password("password123")
user.save()
print(f" ✓ Created user: {user.get_full_name()} ({username})")
# Create Group and assign to user for role
role_name = "PX Admin" if i == 0 else "Staff"
group, _ = Group.objects.get_or_create(name=role_name)
user.groups.add(group)
# Assign hospital to user
user.hospital = hospital
user.save()
else:
print(f" - User already exists: {user.get_full_name()}")
users.append(user)
return users
def create_staff(hospital, departments, users):
"""Create staff members"""
print("\n--- Creating Staff ---")
staff_types = ["physician", "nurse", "admin"]
specializations = ["Cardiology", "General Surgery", "Internal Medicine", "Pediatrics", "Emergency Medicine"]
for i, user in enumerate(users):
dept = random.choice(departments)
staff_type = staff_types[random.randint(0, len(staff_types) - 1)]
staff, created = Staff.objects.get_or_create(
user=user,
defaults={
"first_name": user.first_name,
"last_name": user.last_name,
"first_name_ar": ARABIC_NAMES_FIRST[random.randint(0, len(ARABIC_NAMES_FIRST) - 1)],
"last_name_ar": ARABIC_NAMES_LAST[random.randint(0, len(ARABIC_NAMES_LAST) - 1)],
"staff_type": staff_type,
"job_title": f"{staff_type.title()} - {dept.name}",
"license_number": f"LIC-{random.randint(100000, 999999)}",
"specialization": specializations[random.randint(0, len(specializations) - 1)] if staff_type == "physician" else "",
"email": user.email,
"employee_id": f"EMP-{random.randint(10000, 99999)}",
"hospital": hospital,
"department": dept,
"status": "active"
}
)
if created:
print(f" ✓ Created staff: {staff} ({staff_type})")
else:
print(f" - Staff already exists: {staff}")
def create_patients(hospital, num_patients=10):
"""Create test patients"""
print("\n--- Creating Patients ---")
patients = []
for i in range(num_patients):
first_name = ENGLISH_NAMES_FIRST[random.randint(0, len(ENGLISH_NAMES_FIRST) - 1)]
last_name = ENGLISH_NAMES_LAST[random.randint(0, len(ENGLISH_NAMES_LAST) - 1)]
patient = Patient.objects.create(
mrn=Patient.generate_mrn(),
national_id=f"{''.join([str(random.randint(0, 9)) for _ in range(10)])}",
first_name=first_name,
last_name=last_name,
first_name_ar=ARABIC_NAMES_FIRST[random.randint(0, len(ARABIC_NAMES_FIRST) - 1)],
last_name_ar=ARABIC_NAMES_LAST[random.randint(0, len(ARABIC_NAMES_LAST) - 1)],
date_of_birth=date.today() - timedelta(days=random.randint(18*365, 80*365)),
gender=random.choice(["male", "female"]),
phone=f"+96650{random.randint(1000000, 9999999)}",
email=f"patient{i+1}@test.com",
city=random.choice(["Riyadh", "Jeddah", "Dammam", "Makkah", "Madinah"]),
primary_hospital=hospital,
status="active"
)
patients.append(patient)
print(f" ✓ Created patient: {patient}")
return patients
def create_standard_sources():
"""Create standard sources"""
print("\n--- Creating Standard Sources ---")
sources = []
for source_data in STANDARD_SOURCES:
source, created = StandardSource.objects.get_or_create(
code=source_data["code"],
defaults={
"name": source_data["name"],
"name_ar": source_data["name_ar"],
"description": source_data["description"],
"website": source_data["website"],
"is_active": True
}
)
if created:
print(f" ✓ Created source: {source.name}")
else:
print(f" - Source already exists: {source.name}")
sources.append(source)
return sources
def create_standard_categories():
"""Create standard categories"""
print("\n--- Creating Standard Categories ---")
categories = []
for cat_data in STANDARD_CATEGORIES:
category, created = StandardCategory.objects.get_or_create(
name=cat_data["name"],
defaults={
"name_ar": cat_data["name_ar"],
"description": cat_data["description"],
"order": cat_data["order"],
"is_active": True
}
)
if created:
print(f" ✓ Created category: {category.name}")
else:
print(f" - Category already exists: {category.name}")
categories.append(category)
return categories
def create_standards(sources, categories, departments):
"""Create standards"""
print("\n--- Creating Standards ---")
standards = []
for std_data in STANDARD_TEMPLATES:
# Random source and category
source = sources[random.randint(0, len(sources) - 1)]
category = categories[random.randint(0, len(categories) - 1)]
# Randomly assign to a department (40% chance) or leave null
department = None
if random.random() < 0.4:
department = departments[random.randint(0, len(departments) - 1)]
standard, created = Standard.objects.get_or_create(
code=std_data["code"],
defaults={
"title": std_data["title"],
"title_ar": std_data["title_ar"],
"description": std_data["description"],
"source": source,
"category": category,
"department": department,
"effective_date": date.today() - timedelta(days=random.randint(30, 365)),
"review_date": date.today() + timedelta(days=random.randint(30, 365)),
"is_active": True
}
)
if created:
print(f" ✓ Created standard: {standard.code} - {standard.title}")
else:
print(f" - Standard already exists: {standard.code}")
standards.append(standard)
return standards
def create_compliance_records(departments, standards, users):
"""Create compliance records for all department-standard combinations"""
print("\n--- Creating Compliance Records ---")
status_choices = ["met", "partially_met", "not_met", "not_assessed"]
for dept in departments:
# Get all standards applicable to this department (department-specific or general)
applicable_standards = Standard.objects.filter(
models.Q(department=dept) | models.Q(department__isnull=True)
).filter(is_active=True)
for standard in applicable_standards:
# Check if compliance already exists
if StandardCompliance.objects.filter(department=dept, standard=standard).exists():
print(f" - Compliance exists: {dept.name} - {standard.code}")
continue
# Random status (bias towards met and partially_met)
weights = [0.35, 0.25, 0.15, 0.25] # 35% met, 25% partially_met, 15% not_met, 25% not_assessed
status = random.choices(status_choices, weights=weights, k=1)[0]
# Only add assessor and dates if assessed
assessor = None
last_assessed = None
if status != "not_assessed":
assessor = random.choice(users)
last_assessed = date.today() - timedelta(days=random.randint(1, 90))
compliance = StandardCompliance.objects.create(
department=dept,
standard=standard,
status=status,
last_assessed_date=last_assessed,
assessor=assessor,
notes=f"Assessment completed for {standard.title}" if status != "not_assessed" else "",
evidence_summary=f"Evidence documentation available" if status == "met" else ""
)
status_symbol = "" if status != "not_assessed" else ""
print(f" {status_symbol} Created compliance: {dept.name} - {standard.code} ({status})")
def main():
"""Main function to seed all data"""
print("=" * 70)
print("STANDARDS APP DATA SEEDING SCRIPT")
print("=" * 70)
try:
# Get or create hospital
hospital = get_or_create_hospital()
# Create departments
departments = list(create_departments(hospital))
# Create users
users = create_users(hospital, num_users=5)
# Create staff
create_staff(hospital, departments, users)
# Create patients
patients = create_patients(hospital, num_patients=10)
# Create standard sources
sources = create_standard_sources()
# Create standard categories
categories = create_standard_categories()
# Create standards
standards = create_standards(sources, categories, departments)
# Create compliance records
create_compliance_records(departments, standards, users)
# Print summary
print("\n" + "=" * 70)
print("SEEDING COMPLETE!")
print("=" * 70)
print(f"\nSummary:")
print(f" Hospital: {hospital.name}")
print(f" Departments: {len(departments)}")
print(f" Users: {len(users)}")
print(f" Patients: {len(patients)}")
print(f" Standard Sources: {StandardSource.objects.count()}")
print(f" Standard Categories: {StandardCategory.objects.count()}")
print(f" Standards: {Standard.objects.count()}")
print(f" Compliance Records: {StandardCompliance.objects.count()}")
print(f"\nLogin Credentials:")
for user in users:
print(f" - Username: {user.username}, Password: password123")
print("\n" + "=" * 70)
except Exception as e:
print(f"\n❌ Error during seeding: {str(e)}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == "__main__":
# Import models for the query
from django.db import models as django_models
models = django_models
main()