#!/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()