270 lines
10 KiB
Python
270 lines
10 KiB
Python
import os
|
|
import django
|
|
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hospital_management.settings')
|
|
django.setup()
|
|
|
|
import random
|
|
import uuid
|
|
from datetime import timedelta
|
|
from django.utils import timezone
|
|
from django.contrib.auth import get_user_model
|
|
from analytics.models import (
|
|
Dashboard, DashboardWidget, DataSource,
|
|
Report, ReportExecution, MetricDefinition, MetricValue
|
|
)
|
|
from core.models import Tenant
|
|
|
|
|
|
|
|
User = get_user_model()
|
|
|
|
SAUDI_HOSPITAL_NAMES = [
|
|
"King Faisal Specialist Hospital", "King Saud Medical City", "King Abdulaziz University Hospital",
|
|
"Riyadh Military Hospital", "Dammam Central Hospital", "King Khalid Hospital", "Maternity and Children Hospital"
|
|
]
|
|
|
|
SAUDI_DEPARTMENTS = [
|
|
'Internal Medicine', 'Emergency', 'Cardiology', 'Surgery', 'Radiology',
|
|
'Pharmacy', 'Neurology', 'Obstetrics', 'ICU', 'Pediatrics'
|
|
]
|
|
|
|
|
|
def generate_dashboards(tenants, users):
|
|
dashboards = []
|
|
types = [dt[0] for dt in Dashboard.DashboardType.choices]
|
|
for tenant in tenants:
|
|
for _ in range(random.randint(2, 5)):
|
|
creator = random.choice(users)
|
|
base_name = f"{random.choice(SAUDI_HOSPITAL_NAMES)} Dashboard"
|
|
name = base_name
|
|
counter = 1
|
|
while Dashboard.objects.filter(tenant=tenant, name=name).exists():
|
|
name = f"{base_name} #{counter}"
|
|
counter += 1
|
|
|
|
dashboard = Dashboard.objects.create(
|
|
tenant=tenant,
|
|
name=name,
|
|
description="Analytics for healthcare operations",
|
|
dashboard_type=random.choice(types),
|
|
layout_config={"layout": "grid"},
|
|
refresh_interval=300,
|
|
is_public=random.choice([True, False]),
|
|
is_active=True,
|
|
is_default=random.choice([True, False]),
|
|
created_by=creator
|
|
)
|
|
dashboard.allowed_users.add(creator)
|
|
dashboard.allowed_roles = [creator.employee_profile.role]
|
|
dashboard.save()
|
|
dashboards.append(dashboard)
|
|
print(f"✅ Created {len(dashboards)} dashboards")
|
|
return dashboards
|
|
|
|
|
|
def generate_data_sources(tenants, users):
|
|
data_sources = []
|
|
for tenant in tenants:
|
|
for _ in range(random.randint(2, 4)):
|
|
creator = random.choice(users)
|
|
base_name = f"{random.choice(SAUDI_DEPARTMENTS)} Source"
|
|
name = base_name
|
|
counter = 1
|
|
while DataSource.objects.filter(tenant=tenant, name=name).exists():
|
|
name = f"{base_name} #{counter}"
|
|
counter += 1
|
|
|
|
ds = DataSource.objects.create(
|
|
tenant=tenant,
|
|
name=name,
|
|
description=f"Source for {name}",
|
|
source_type="DATABASE",
|
|
connection_type="POSTGRESQL",
|
|
connection_config={"host": "db.hospital.local", "port": 5432},
|
|
authentication_config={"user": "readonly", "password": "secure"},
|
|
query_template="SELECT * FROM department_data WHERE department = %s",
|
|
parameters={"department": random.choice(SAUDI_DEPARTMENTS)},
|
|
data_transformation={"columns": ["metric1", "metric2"]},
|
|
cache_duration=300,
|
|
is_active=True,
|
|
is_healthy=True,
|
|
health_check_interval=300,
|
|
last_health_check=timezone.now(),
|
|
last_test_status='SUCCESS',
|
|
created_by=creator
|
|
)
|
|
data_sources.append(ds)
|
|
print(f"✅ Created {len(data_sources)} data sources")
|
|
return data_sources
|
|
|
|
|
|
def generate_widgets(dashboards, data_sources):
|
|
widgets = []
|
|
for dashboard in dashboards:
|
|
for _ in range(random.randint(2, 6)):
|
|
ds = random.choice(data_sources)
|
|
widget = DashboardWidget.objects.create(
|
|
dashboard=dashboard,
|
|
name=f"{random.choice(['Admissions', 'Lab Turnaround', 'Bed Occupancy'])} Widget",
|
|
widget_type="CHART",
|
|
chart_type=random.choice(['LINE', 'BAR', 'PIE']),
|
|
data_source=ds,
|
|
query_config={"table": "metrics"},
|
|
position_x=random.randint(0, 3),
|
|
position_y=random.randint(0, 3),
|
|
width=random.randint(3, 6),
|
|
height=random.randint(2, 4),
|
|
display_config={"color": "blue"},
|
|
auto_refresh=True,
|
|
refresh_interval=300,
|
|
is_active=True
|
|
)
|
|
widgets.append(widget)
|
|
print(f"✅ Created {len(widgets)} widgets")
|
|
return widgets
|
|
|
|
|
|
def generate_reports(tenants, data_sources, users):
|
|
reports = []
|
|
for tenant in tenants:
|
|
for _ in range(random.randint(2, 5)):
|
|
creator = random.choice(users)
|
|
ds = random.choice(data_sources)
|
|
|
|
base_name = f"{random.choice(['Inpatient Report', 'ER Load', 'Daily Discharges'])}"
|
|
name = base_name
|
|
counter = 1
|
|
while Report.objects.filter(tenant=tenant, name=name).exists():
|
|
name = f"{base_name} #{counter}"
|
|
counter += 1
|
|
|
|
report = Report.objects.create(
|
|
tenant=tenant,
|
|
name=name,
|
|
description=f"Auto-generated report for {name}",
|
|
report_type="CLINICAL",
|
|
data_source=ds,
|
|
query_config={"sql": "SELECT * FROM report_data"},
|
|
output_format=random.choice(["PDF", "EXCEL", "CSV"]),
|
|
template_config={"header": "Hospital Report"},
|
|
schedule_type=random.choice(["DAILY", "WEEKLY"]),
|
|
schedule_config={"time": "06:00"},
|
|
next_execution=timezone.now() + timedelta(days=1),
|
|
recipients=[creator.email],
|
|
distribution_config={"method": "EMAIL"},
|
|
is_active=True,
|
|
created_by=creator
|
|
)
|
|
reports.append(report)
|
|
print(f"✅ Created {len(reports)} reports")
|
|
return reports
|
|
|
|
|
|
def generate_report_executions(reports, users):
|
|
executions = []
|
|
for report in reports:
|
|
for _ in range(random.randint(1, 3)):
|
|
status = random.choice(['COMPLETED', 'FAILED'])
|
|
start_time = timezone.now() - timedelta(days=random.randint(1, 10))
|
|
end_time = start_time + timedelta(minutes=random.randint(1, 30))
|
|
duration = int((end_time - start_time).total_seconds())
|
|
|
|
execution = ReportExecution.objects.create(
|
|
report=report,
|
|
execution_type="SCHEDULED",
|
|
started_at=start_time,
|
|
completed_at=end_time,
|
|
duration_seconds=duration,
|
|
status=status,
|
|
error_message="" if status == 'COMPLETED' else "Timeout",
|
|
output_file_path=f"/reports/{uuid.uuid4()}.pdf",
|
|
output_size_bytes=random.randint(50000, 500000),
|
|
record_count=random.randint(100, 1000),
|
|
execution_parameters={"param1": "value"},
|
|
executed_by=random.choice(users)
|
|
)
|
|
executions.append(execution)
|
|
print(f"✅ Created {len(executions)} report executions")
|
|
return executions
|
|
|
|
|
|
def generate_metrics(tenants, data_sources, users):
|
|
metrics = []
|
|
for tenant in tenants:
|
|
for _ in range(random.randint(3, 7)):
|
|
creator = random.choice(users)
|
|
ds = random.choice(data_sources)
|
|
|
|
base_name = random.choice(['ER Wait Time', 'Readmission Rate', 'Avg Length of Stay'])
|
|
name = base_name
|
|
counter = 1
|
|
while MetricDefinition.objects.filter(tenant=tenant, name=name).exists():
|
|
name = f"{base_name} #{counter}"
|
|
counter += 1
|
|
|
|
metric = MetricDefinition.objects.create(
|
|
tenant=tenant,
|
|
name=name,
|
|
description=f"Metric tracking {name.lower()}",
|
|
metric_type="AVERAGE",
|
|
data_source=ds,
|
|
calculation_config={"sql": "SELECT AVG(value) FROM metric_table"},
|
|
aggregation_period="DAILY",
|
|
aggregation_config={"group_by": "date"},
|
|
target_value=5.0,
|
|
warning_threshold=7.0,
|
|
critical_threshold=10.0,
|
|
unit_of_measure="days",
|
|
decimal_places=2,
|
|
display_format="number",
|
|
is_active=True,
|
|
created_by=creator
|
|
)
|
|
metrics.append(metric)
|
|
print(f"✅ Created {len(metrics)} metric definitions")
|
|
return metrics
|
|
|
|
|
|
def generate_metric_values(metrics):
|
|
values = []
|
|
for metric in metrics:
|
|
for i in range(7): # one week of data
|
|
start = timezone.now() - timedelta(days=i)
|
|
value = MetricValue.objects.create(
|
|
metric_definition=metric,
|
|
value=round(random.uniform(3.0, 10.0), 2),
|
|
period_start=start.replace(hour=0, minute=0, second=0),
|
|
period_end=start.replace(hour=23, minute=59, second=59),
|
|
dimensions={"department": random.choice(SAUDI_DEPARTMENTS)},
|
|
metadata={"source": "daily_batch"},
|
|
data_quality_score=round(random.uniform(85, 100), 2),
|
|
confidence_level=round(random.uniform(90, 100), 2),
|
|
calculation_duration_ms=random.randint(50, 500)
|
|
)
|
|
values.append(value)
|
|
print(f"✅ Created {len(values)} metric values")
|
|
return values
|
|
|
|
|
|
def main():
|
|
tenants = list(Tenant.objects.all())
|
|
users = list(User.objects.filter(is_active=True))
|
|
|
|
if not tenants or not users:
|
|
print("❌ Tenants or Users not available.")
|
|
return
|
|
|
|
dashboards = generate_dashboards(tenants, users)
|
|
data_sources = generate_data_sources(tenants, users)
|
|
widgets = generate_widgets(dashboards, data_sources)
|
|
reports = generate_reports(tenants, data_sources, users)
|
|
executions = generate_report_executions(reports, users)
|
|
metrics = generate_metrics(tenants, data_sources, users)
|
|
metric_values = generate_metric_values(metrics)
|
|
|
|
print("\n🎉 Saudi Analytics Data Generation Complete!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |