203 lines
7.7 KiB
Python
203 lines
7.7 KiB
Python
"""
|
|
Management command to seed standard departments for hospitals
|
|
|
|
Creates 5 standard departments for hospitals:
|
|
1. EMR-001 - Emergency & Urgent Care / الطوارئ والرعاية العاجلة
|
|
2. OUT-002 - Outpatient & Specialist Clinics / العيادات الخارجية والعيادات المتخصصة
|
|
3. INP-003 - Inpatient & Surgical Services / خدمات العلاج الداخلي والجراحة
|
|
4. DIA-004 - Diagnostics & Laboratory Services / خدمات التشخيص والمختبرات
|
|
5. ADM-005 - Administration & Support Services / خدمات الإدارة والدعم
|
|
"""
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
from django.db import transaction
|
|
|
|
from apps.organizations.models import Hospital, Department
|
|
|
|
|
|
# Standard departments configuration
|
|
STANDARD_DEPARTMENTS = [
|
|
{
|
|
'code': 'EMR-001',
|
|
'name': 'Emergency & Urgent Care',
|
|
'name_ar': 'الطوارئ والرعاية العاجلة',
|
|
'order': 1
|
|
},
|
|
{
|
|
'code': 'OUT-002',
|
|
'name': 'Outpatient & Specialist Clinics',
|
|
'name_ar': 'العيادات الخارجية والعيادات المتخصصة',
|
|
'order': 2
|
|
},
|
|
{
|
|
'code': 'INP-003',
|
|
'name': 'Inpatient & Surgical Services',
|
|
'name_ar': 'خدمات العلاج الداخلي والجراحة',
|
|
'order': 3
|
|
},
|
|
{
|
|
'code': 'DIA-004',
|
|
'name': 'Diagnostics & Laboratory Services',
|
|
'name_ar': 'خدمات التشخيص والمختبرات',
|
|
'order': 4
|
|
},
|
|
{
|
|
'code': 'ADM-005',
|
|
'name': 'Administration & Support Services',
|
|
'name_ar': 'خدمات الإدارة والدعم',
|
|
'order': 5
|
|
},
|
|
]
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Seed standard departments for hospitals'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
'--hospital-code',
|
|
type=str,
|
|
help='Target hospital code (default: all hospitals)'
|
|
)
|
|
parser.add_argument(
|
|
'--dry-run',
|
|
action='store_true',
|
|
help='Preview without making changes'
|
|
)
|
|
parser.add_argument(
|
|
'--overwrite',
|
|
action='store_true',
|
|
help='Overwrite existing departments with same codes'
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
hospital_code = options['hospital_code']
|
|
dry_run = options['dry_run']
|
|
overwrite = options['overwrite']
|
|
|
|
self.stdout.write(f"\n{'='*60}")
|
|
self.stdout.write("Standard Departments Seeding Command")
|
|
self.stdout.write(f"{'='*60}\n")
|
|
|
|
# Get hospitals
|
|
if hospital_code:
|
|
hospitals = Hospital.objects.filter(code=hospital_code)
|
|
if not hospitals.exists():
|
|
self.stdout.write(
|
|
self.style.ERROR(f"Hospital with code '{hospital_code}' not found")
|
|
)
|
|
return
|
|
else:
|
|
hospitals = Hospital.objects.filter(status='active')
|
|
|
|
if not hospitals.exists():
|
|
self.stdout.write(
|
|
self.style.ERROR("No active hospitals found.")
|
|
)
|
|
return
|
|
|
|
self.stdout.write(
|
|
self.style.SUCCESS(f"Found {hospitals.count()} hospital(s) to seed departments")
|
|
)
|
|
|
|
# Display configuration
|
|
self.stdout.write("\nConfiguration:")
|
|
self.stdout.write(f" Departments to create: {len(STANDARD_DEPARTMENTS)}")
|
|
self.stdout.write(f" Overwrite existing: {overwrite}")
|
|
self.stdout.write(f" Dry run: {dry_run}")
|
|
|
|
# Display departments
|
|
self.stdout.write("\nStandard Departments:")
|
|
for dept in STANDARD_DEPARTMENTS:
|
|
self.stdout.write(
|
|
f" {dept['code']} - {dept['name']} / {dept['name_ar']}"
|
|
)
|
|
|
|
# Track created/skipped departments
|
|
stats = {
|
|
'created': 0,
|
|
'skipped': 0,
|
|
'updated': 0,
|
|
'errors': 0
|
|
}
|
|
|
|
# Seed departments for each hospital
|
|
for hospital in hospitals:
|
|
self.stdout.write(f"\nProcessing hospital: {hospital.name} ({hospital.code})")
|
|
|
|
for dept_config in STANDARD_DEPARTMENTS:
|
|
# Check if department already exists
|
|
existing_dept = Department.objects.filter(
|
|
hospital=hospital,
|
|
code=dept_config['code']
|
|
).first()
|
|
|
|
if existing_dept:
|
|
if overwrite:
|
|
if dry_run:
|
|
self.stdout.write(
|
|
f" Would update: {dept_config['code']} - {dept_config['name']}"
|
|
)
|
|
stats['updated'] += 1
|
|
else:
|
|
# Update existing department
|
|
existing_dept.name = dept_config['name']
|
|
existing_dept.name_ar = dept_config['name_ar']
|
|
existing_dept.save(update_fields=['name', 'name_ar'])
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f" ✓ Updated: {dept_config['code']} - {dept_config['name']}"
|
|
)
|
|
)
|
|
stats['updated'] += 1
|
|
else:
|
|
self.stdout.write(
|
|
self.style.WARNING(
|
|
f" ⊘ Skipped: {dept_config['code']} already exists"
|
|
)
|
|
)
|
|
stats['skipped'] += 1
|
|
else:
|
|
# Create new department
|
|
if dry_run:
|
|
self.stdout.write(
|
|
f" Would create: {dept_config['code']} - {dept_config['name']}"
|
|
)
|
|
stats['created'] += 1
|
|
else:
|
|
try:
|
|
Department.objects.create(
|
|
hospital=hospital,
|
|
code=dept_config['code'],
|
|
name=dept_config['name'],
|
|
name_ar=dept_config['name_ar'],
|
|
status='active'
|
|
)
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f" ✓ Created: {dept_config['code']} - {dept_config['name']}"
|
|
)
|
|
)
|
|
stats['created'] += 1
|
|
except Exception as e:
|
|
self.stdout.write(
|
|
self.style.ERROR(
|
|
f" ✗ Failed to create {dept_config['code']}: {str(e)}"
|
|
)
|
|
)
|
|
stats['errors'] += 1
|
|
|
|
# Summary
|
|
self.stdout.write("\n" + "="*60)
|
|
self.stdout.write("Summary:")
|
|
self.stdout.write(f" Hospitals processed: {hospitals.count()}")
|
|
self.stdout.write(f" Departments created: {stats['created']}")
|
|
self.stdout.write(f" Departments updated: {stats['updated']}")
|
|
self.stdout.write(f" Departments skipped: {stats['skipped']}")
|
|
self.stdout.write(f" Errors: {stats['errors']}")
|
|
self.stdout.write("="*60 + "\n")
|
|
|
|
if dry_run:
|
|
self.stdout.write(self.style.WARNING("DRY RUN: No changes were made\n"))
|
|
else:
|
|
self.stdout.write(self.style.SUCCESS("Department seeding completed successfully!\n"))
|