hospital-management/accounts_data.py
2025-08-12 13:33:25 +03:00

457 lines
18 KiB
Python

import os
import django
# Set up Django environment
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hospital_management.settings')
django.setup()
import random
from datetime import datetime, timedelta, timezone
from django.contrib.auth.hashers import make_password
from django.utils import timezone as django_timezone
from accounts.models import User, TwoFactorDevice, SocialAccount, UserSession, PasswordHistory
from core.models import Tenant
import uuid
import secrets
# Saudi-specific data constants
SAUDI_FIRST_NAMES_MALE = [
'Mohammed', 'Abdullah', 'Ahmed', 'Omar', 'Ali', 'Hassan', 'Khalid', 'Faisal',
'Saad', 'Fahd', 'Bandar', 'Turki', 'Nasser', 'Saud', 'Abdulrahman',
'Abdulaziz', 'Salman', 'Waleed', 'Majid', 'Rayan', 'Yazeed', 'Mansour',
'Osama', 'Tariq', 'Adel', 'Nawaf', 'Sultan', 'Mishaal', 'Badr', 'Ziad'
]
SAUDI_FIRST_NAMES_FEMALE = [
'Fatima', 'Aisha', 'Maryam', 'Khadija', 'Sarah', 'Noura', 'Hala', 'Reem',
'Lina', 'Dana', 'Rana', 'Nada', 'Layla', 'Amira', 'Zahra', 'Yasmin',
'Dina', 'Noor', 'Rahma', 'Salma', 'Lama', 'Ghada', 'Rania', 'Maha',
'Wedad', 'Najla', 'Shahd', 'Jood', 'Rand', 'Malak'
]
SAUDI_FAMILY_NAMES = [
'Al-Rashid', 'Al-Harbi', 'Al-Qahtani', 'Al-Dosari', 'Al-Otaibi', 'Al-Mutairi',
'Al-Shammari', 'Al-Zahrani', 'Al-Ghamdi', 'Al-Maliki', 'Al-Subai', 'Al-Jubayr',
'Al-Faisal', 'Al-Saud', 'Al-Thani', 'Al-Maktoum', 'Al-Sabah', 'Al-Khalifa',
'Bin-Laden', 'Al-Rajhi', 'Al-Sudairy', 'Al-Shaalan', 'Al-Kabeer', 'Al-Ajmi',
'Al-Anzi', 'Al-Dawsari', 'Al-Shamrani', 'Al-Balawi', 'Al-Juhani', 'Al-Sulami'
]
SAUDI_MIDDLE_NAMES = [
'bin Ahmed', 'bin Mohammed', 'bin Abdullah', 'bin Omar', 'bin Ali', 'bin Hassan',
'bin Khalid', 'bin Faisal', 'bin Saad', 'bin Fahd', 'bin Abdulaziz', 'bin Salman'
]
SAUDI_CITIES = [
'Riyadh', 'Jeddah', 'Mecca', 'Medina', 'Dammam', 'Khobar', 'Dhahran',
'Taif', 'Tabuk', 'Buraidah', 'Khamis Mushait', 'Hofuf', 'Mubarraz',
'Jubail', 'Yanbu', 'Abha', 'Najran', 'Jazan', 'Hail', 'Arar'
]
SAUDI_PROVINCES = [
'Riyadh Province', 'Makkah Province', 'Eastern Province', 'Asir Province',
'Jazan Province', 'Medina Province', 'Qassim Province', 'Tabuk Province',
'Hail Province', 'Northern Borders Province', 'Najran Province', 'Al Bahah Province'
]
SAUDI_JOB_TITLES = {
'PHYSICIAN': ['Consultant Physician', 'Senior Physician', 'Staff Physician', 'Resident Physician',
'Chief Medical Officer'],
'NURSE': ['Head Nurse', 'Senior Nurse', 'Staff Nurse', 'Charge Nurse', 'Clinical Nurse Specialist'],
'PHARMACIST': ['Clinical Pharmacist', 'Staff Pharmacist', 'Pharmacy Manager', 'Pharmaceutical Consultant'],
'ADMIN': ['Medical Director', 'Hospital Administrator', 'Department Manager', 'Operations Manager'],
'LAB_TECH': ['Senior Lab Technician', 'Medical Laboratory Scientist', 'Lab Supervisor'],
'RAD_TECH': ['Senior Radiologic Technologist', 'CT Technologist', 'MRI Technologist'],
'RADIOLOGIST': ['Consultant Radiologist', 'Senior Radiologist', 'Interventional Radiologist']
}
SAUDI_DEPARTMENTS = [
'Internal Medicine', 'Cardiology', 'Orthopedics', 'Neurology', 'Oncology',
'Pediatrics', 'Emergency Medicine', 'Radiology', 'Laboratory Medicine',
'Pharmacy', 'Surgery', 'Obstetrics and Gynecology', 'Dermatology',
'Ophthalmology', 'ENT', 'Anesthesiology', 'Pathology', 'Psychiatry'
]
# Saudi Medical License Formats
SAUDI_LICENSE_PREFIXES = ['MOH', 'SCFHS', 'SMLE', 'SFH']
def generate_saudi_phone():
"""Generate Saudi phone number"""
area_codes = ['11', '12', '13', '14', '16', '17'] # Major Saudi area codes
return f"+966-{random.choice(area_codes)}-{random.randint(100, 999)}-{random.randint(1000, 9999)}"
def generate_saudi_mobile():
"""Generate Saudi mobile number"""
mobile_prefixes = ['50', '53', '54', '55', '56', '57', '58', '59'] # Saudi mobile prefixes
return f"+966-{random.choice(mobile_prefixes)}-{random.randint(100, 999)}-{random.randint(1000, 9999)}"
def generate_saudi_license():
"""Generate Saudi medical license number"""
prefix = random.choice(SAUDI_LICENSE_PREFIXES)
return f"{prefix}-{random.randint(100000, 999999)}"
def generate_saudi_employee_id(tenant_name, role):
"""Generate Saudi employee ID"""
tenant_code = ''.join([c for c in tenant_name.upper() if c.isalpha()])[:3]
role_code = role[:3].upper()
return f"{tenant_code}-{role_code}-{random.randint(1000, 9999)}"
def create_saudi_users(tenants, users_per_tenant=50):
"""Create Saudi healthcare users"""
users = []
role_distribution = {
'PHYSICIAN': 0.15,
'NURSE': 0.25,
'PHARMACIST': 0.08,
'LAB_TECH': 0.10,
'RAD_TECH': 0.08,
'RADIOLOGIST': 0.05,
'ADMIN': 0.07,
'MEDICAL_ASSISTANT': 0.12,
'CLERICAL': 0.10
}
for tenant in tenants:
tenant_users = []
for role, percentage in role_distribution.items():
user_count = max(1, int(users_per_tenant * percentage))
for i in range(user_count):
# Determine gender for Arabic naming
is_male = random.choice([True, False])
first_name = random.choice(SAUDI_FIRST_NAMES_MALE if is_male else SAUDI_FIRST_NAMES_FEMALE)
last_name = random.choice(SAUDI_FAMILY_NAMES)
middle_name = random.choice(SAUDI_MIDDLE_NAMES) if random.choice([True, False]) else None
# Generate username
username = f"{first_name.lower()}.{last_name.lower().replace('-', '').replace('al', '')}"
counter = 1
original_username = username
while User.objects.filter(username=username).exists():
username = f"{original_username}{counter}"
counter += 1
# Generate email
email = f"{username}@{tenant.name.lower().replace(' ', '').replace('-', '')}.sa"
# Professional information
department = random.choice(SAUDI_DEPARTMENTS)
job_title = random.choice(SAUDI_JOB_TITLES.get(role, [f"{role.replace('_', ' ').title()}"]))
# License information for medical professionals
license_number = None
license_state = None
license_expiry = None
npi_number = None
if role in ['PHYSICIAN', 'NURSE', 'PHARMACIST', 'RADIOLOGIST']:
license_number = generate_saudi_license()
license_state = random.choice(SAUDI_PROVINCES)
license_expiry = django_timezone.now().date() + timedelta(days=random.randint(365, 1095))
if role == 'PHYSICIAN':
npi_number = f"SA{random.randint(1000000, 9999999)}"
user = User.objects.create(
username=username,
email=email,
first_name=first_name,
last_name=last_name,
middle_name=middle_name,
preferred_name=first_name if random.choice([True, False]) else None,
tenant=tenant,
# Contact information
phone_number=generate_saudi_phone(),
mobile_number=generate_saudi_mobile(),
# Professional information
employee_id=generate_saudi_employee_id(tenant.name, role),
department=department,
job_title=job_title,
role=role,
# License information
license_number=license_number,
license_state=license_state,
license_expiry=license_expiry,
npi_number=npi_number,
# Security settings
force_password_change=random.choice([True, False]),
password_expires_at=django_timezone.now() + timedelta(days=random.randint(90, 365)),
failed_login_attempts=random.randint(0, 2),
two_factor_enabled=random.choice([True, False]) if role in ['PHYSICIAN', 'ADMIN',
'PHARMACIST'] else False,
# Session settings
max_concurrent_sessions=random.choice([1, 2, 3, 5]),
session_timeout_minutes=random.choice([30, 60, 120, 240]),
# Preferences
user_timezone='Asia/Riyadh',
language=random.choice(['ar', 'en', 'ar_SA']),
theme=random.choice(['LIGHT', 'DARK', 'AUTO']),
# Status
is_verified=True,
is_approved=True,
approval_date=django_timezone.now() - timedelta(days=random.randint(1, 180)),
is_active=True,
is_staff=role in ['ADMIN', 'SUPER_ADMIN'],
is_superuser=role == 'SUPER_ADMIN',
# Metadata
created_at=django_timezone.now() - timedelta(days=random.randint(1, 365)),
updated_at=django_timezone.now() - timedelta(days=random.randint(0, 30)),
last_password_change=django_timezone.now() - timedelta(days=random.randint(1, 90)),
date_joined=django_timezone.now() - timedelta(days=random.randint(1, 365))
)
# Set password
user.set_password('Hospital@123') # Default password
user.save()
users.append(user)
tenant_users.append(user)
# Set approval relationships
admin_users = [u for u in tenant_users if u.role in ['ADMIN', 'SUPER_ADMIN']]
if admin_users:
approver = random.choice(admin_users)
for user in tenant_users:
if user != approver and user.role != 'SUPER_ADMIN':
user.approved_by = approver
user.save()
print(f"Created {len(tenant_users)} users for {tenant.name}")
return users
def create_saudi_two_factor_devices(users):
"""Create two-factor authentication devices for Saudi users"""
devices = []
device_types = ['TOTP', 'SMS', 'EMAIL']
device_names = {
'TOTP': ['Google Authenticator', 'Microsoft Authenticator', 'Authy', 'LastPass Authenticator'],
'SMS': ['Primary Mobile', 'Work Mobile', 'Emergency Contact'],
'EMAIL': ['Work Email', 'Personal Email', 'Backup Email']
}
for user in users:
if user.two_factor_enabled:
# Create 1-3 devices per user
device_count = random.randint(1, 3)
for _ in range(device_count):
device_type = random.choice(device_types)
device_data = {
'user': user,
'device_id': uuid.uuid4(),
'name': random.choice(device_names[device_type]),
'device_type': device_type,
'is_active': True,
'is_verified': True,
'verified_at': django_timezone.now() - timedelta(days=random.randint(1, 30)),
'last_used_at': django_timezone.now() - timedelta(hours=random.randint(1, 168)),
'usage_count': random.randint(5, 100),
'created_at': django_timezone.now() - timedelta(days=random.randint(1, 60))
}
if device_type == 'TOTP':
device_data['secret_key'] = secrets.token_urlsafe(32)
elif device_type == 'SMS':
device_data['phone_number'] = user.mobile_number
elif device_type == 'EMAIL':
device_data['email_address'] = user.email
device = TwoFactorDevice.objects.create(**device_data)
devices.append(device)
print(f"Created {len(devices)} two-factor devices")
return devices
def create_saudi_social_accounts(users):
"""Create social authentication accounts for Saudi users"""
social_accounts = []
# Common providers in Saudi Arabia
providers = ['GOOGLE', 'MICROSOFT', 'APPLE', 'LINKEDIN']
for user in users:
# 30% chance of having social accounts
if random.choice([True, False, False, False]):
provider = random.choice(providers)
social_account = SocialAccount.objects.create(
user=user,
provider=provider,
provider_id=f"{provider.lower()}_{random.randint(100000000, 999999999)}",
provider_email=user.email,
display_name=user.get_full_name(),
profile_url=f"https://{provider.lower()}.com/profile/{user.username}",
avatar_url=f"https://{provider.lower()}.com/avatar/{user.username}.jpg",
access_token=secrets.token_urlsafe(64),
refresh_token=secrets.token_urlsafe(64),
token_expires_at=django_timezone.now() + timedelta(hours=1),
is_active=True,
created_at=django_timezone.now() - timedelta(days=random.randint(1, 180)),
last_login_at=django_timezone.now() - timedelta(hours=random.randint(1, 48))
)
social_accounts.append(social_account)
print(f"Created {len(social_accounts)} social accounts")
return social_accounts
def create_saudi_user_sessions(users):
"""Create user sessions for Saudi healthcare users"""
sessions = []
saudi_ips = [
'37.99.', '37.200.', '31.9.', '31.173.', '188.161.',
'185.84.', '188.245.', '217.9.', '82.205.', '5.63.'
]
browsers = [
'Chrome 120.0.0.0', 'Safari 17.1.2', 'Firefox 121.0.0', 'Edge 120.0.0.0',
'Chrome Mobile 120.0.0.0', 'Safari Mobile 17.1.2'
]
operating_systems = [
'Windows 11', 'Windows 10', 'macOS 14.0', 'iOS 17.1.2',
'Android 14', 'Ubuntu 22.04'
]
device_types = ['DESKTOP', 'MOBILE', 'TABLET']
login_methods = ['PASSWORD', 'TWO_FACTOR', 'SOCIAL', 'SSO']
for user in users:
# Create 1-5 sessions per user
session_count = random.randint(1, 5)
for i in range(session_count):
ip_prefix = random.choice(saudi_ips)
ip_address = f"{ip_prefix}{random.randint(1, 255)}.{random.randint(1, 255)}"
session_start = django_timezone.now() - timedelta(hours=random.randint(1, 720))
is_active = i == 0 and random.choice([True, True, False]) # Most recent session likely active
session = UserSession.objects.create(
user=user,
session_key=f"session_{secrets.token_urlsafe(20)}",
session_id=uuid.uuid4(),
ip_address=ip_address,
user_agent=f"Mozilla/5.0 (compatible; HospitalSystem/1.0; {random.choice(browsers)})",
device_type=random.choice(device_types),
browser=random.choice(browsers),
operating_system=random.choice(operating_systems),
country='Saudi Arabia',
region=random.choice(SAUDI_PROVINCES),
city=random.choice(SAUDI_CITIES),
is_active=is_active,
login_method=random.choice(login_methods),
created_at=session_start,
last_activity_at=session_start + timedelta(minutes=random.randint(1, 480)),
expires_at=session_start + timedelta(hours=user.session_timeout_minutes // 60),
ended_at=None if is_active else session_start + timedelta(hours=random.randint(1, 8))
)
sessions.append(session)
print(f"Created {len(sessions)} user sessions")
return sessions
def create_saudi_password_history(users):
"""Create password history for Saudi users"""
password_history = []
passwords = ['Hospital@123', 'Medical@456', 'Health@789', 'Saudi@2024', 'Secure@Pass']
for user in users:
# Create 1-5 password history entries per user
history_count = random.randint(1, 5)
for i in range(history_count):
password = random.choice(passwords)
history_entry = PasswordHistory.objects.create(
user=user,
password_hash=make_password(password),
created_at=django_timezone.now() - timedelta(days=random.randint(30 * i, 30 * (i + 1)))
)
password_history.append(history_entry)
print(f"Created {len(password_history)} password history entries")
return password_history
def main():
"""Main function to generate all Saudi accounts data"""
print("Starting Saudi Healthcare Accounts Data Generation...")
# Get existing tenants
tenants = list(Tenant.objects.all())
if not tenants:
print("❌ No tenants found. Please run the core data generator first.")
return
# Create users
print("\n1. Creating Saudi Healthcare Users...")
users = create_saudi_users(tenants, 40) # 40 users per tenant
# Create two-factor devices
print("\n2. Creating Two-Factor Authentication Devices...")
devices = create_saudi_two_factor_devices(users)
# Create social accounts
print("\n3. Creating Social Authentication Accounts...")
social_accounts = create_saudi_social_accounts(users)
# Create user sessions
print("\n4. Creating User Sessions...")
sessions = create_saudi_user_sessions(users)
# Create password history
print("\n5. Creating Password History...")
password_history = create_saudi_password_history(users)
print(f"\n✅ Saudi Healthcare Accounts Data Generation Complete!")
print(f"📊 Summary:")
print(f" - Users: {len(users)}")
print(f" - Two-Factor Devices: {len(devices)}")
print(f" - Social Accounts: {len(social_accounts)}")
print(f" - User Sessions: {len(sessions)}")
print(f" - Password History Entries: {len(password_history)}")
# Role distribution summary
role_counts = {}
for user in users:
role_counts[user.role] = role_counts.get(user.role, 0) + 1
print(f"\n👥 User Role Distribution:")
for role, count in sorted(role_counts.items()):
print(f" - {role.replace('_', ' ').title()}: {count}")
return {
'users': users,
'devices': devices,
'social_accounts': social_accounts,
'sessions': sessions,
'password_history': password_history
}
if __name__ == "__main__":
main()