190 lines
6.1 KiB
Python
190 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Script to update all remaining apps to use core models.
|
||
Updates patient, encounter, and facility FK references.
|
||
"""
|
||
|
||
import re
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
# Apps to update with their specific changes needed
|
||
APPS_TO_UPDATE = {
|
||
'billing': {
|
||
'patient_fk': True,
|
||
'encounter_fk': True,
|
||
'facility_fk': False,
|
||
},
|
||
'pharmacy': {
|
||
'patient_fk': True,
|
||
'encounter_fk': True,
|
||
'facility_fk': False,
|
||
},
|
||
'laboratory': {
|
||
'patient_fk': True,
|
||
'encounter_fk': True,
|
||
'facility_fk': False,
|
||
},
|
||
'radiology': {
|
||
'patient_fk': True,
|
||
'encounter_fk': True,
|
||
'facility_fk': False,
|
||
},
|
||
'operating_theatre': {
|
||
'patient_fk': True,
|
||
'encounter_fk': True,
|
||
'facility_fk': True,
|
||
},
|
||
'inpatients': {
|
||
'patient_fk': True,
|
||
'encounter_fk': True,
|
||
'facility_fk': False,
|
||
},
|
||
'blood_bank': {
|
||
'patient_fk': True,
|
||
'encounter_fk': False,
|
||
'facility_fk': False,
|
||
},
|
||
'appointments': {
|
||
'patient_fk': True,
|
||
'encounter_fk': False,
|
||
'facility_fk': False,
|
||
},
|
||
'facility_management': {
|
||
'patient_fk': False,
|
||
'encounter_fk': False,
|
||
'facility_fk': True,
|
||
},
|
||
}
|
||
|
||
def update_app_models(app_name, changes_needed):
|
||
"""Update a single app's models.py file."""
|
||
|
||
models_path = Path(f'{app_name}/models.py')
|
||
|
||
if not models_path.exists():
|
||
print(f"⚠️ {app_name}/models.py not found, skipping...")
|
||
return False
|
||
|
||
print(f"\n📝 Processing {app_name}/models.py...")
|
||
content = models_path.read_text(encoding='utf-8')
|
||
|
||
# Track if any changes were made
|
||
changes_made = False
|
||
|
||
# Step 1: Check if imports already exist
|
||
has_core_imports = 'from core.models import' in content
|
||
|
||
if not has_core_imports:
|
||
print(f" ➕ Adding core imports...")
|
||
|
||
# Build import list based on what's needed
|
||
imports = []
|
||
if changes_needed['patient_fk']:
|
||
imports.append('Patient')
|
||
if changes_needed['encounter_fk']:
|
||
imports.append('Encounter')
|
||
if changes_needed['facility_fk']:
|
||
imports.append('Facility')
|
||
imports.append('TenantScopedModel')
|
||
|
||
import_line = f"\n# Import core models\nfrom core.models import {', '.join(imports)}\n"
|
||
|
||
# Find a good place to insert (after other imports, before first class)
|
||
# Look for the last import statement
|
||
import_pattern = r'((?:from|import)\s+[\w.]+.*\n)+'
|
||
match = re.search(import_pattern, content)
|
||
|
||
if match:
|
||
insert_pos = match.end()
|
||
content = content[:insert_pos] + import_line + content[insert_pos:]
|
||
changes_made = True
|
||
else:
|
||
# Fallback: insert after docstring
|
||
docstring_pattern = r'"""[\s\S]*?"""'
|
||
match = re.search(docstring_pattern, content)
|
||
if match:
|
||
insert_pos = match.end()
|
||
content = content[:insert_pos] + "\n" + import_line + content[insert_pos:]
|
||
changes_made = True
|
||
|
||
# Step 2: Update patient FK references
|
||
if changes_needed['patient_fk']:
|
||
old_patient_refs = content.count("'patients.PatientProfile'")
|
||
if old_patient_refs > 0:
|
||
print(f" 🔄 Updating {old_patient_refs} patient FK reference(s)...")
|
||
content = content.replace("'patients.PatientProfile'", "'core.Patient'")
|
||
changes_made = True
|
||
|
||
# Step 3: Update encounter FK references
|
||
if changes_needed['encounter_fk']:
|
||
old_encounter_refs = content.count("'emr.Encounter'")
|
||
if old_encounter_refs > 0:
|
||
print(f" 🔄 Updating {old_encounter_refs} encounter FK reference(s)...")
|
||
content = content.replace("'emr.Encounter'", "'core.Encounter'")
|
||
changes_made = True
|
||
|
||
# Step 4: Update facility FK references (if app has local Facility model)
|
||
if changes_needed['facility_fk']:
|
||
# This is more complex - need to check if app has its own Facility model
|
||
if 'class Facility(models.Model)' in content or 'class Facility(TenantScopedModel)' in content:
|
||
print(f" ⚠️ {app_name} has local Facility model - manual review needed!")
|
||
|
||
old_facility_refs = content.count(f"'{app_name}.Facility'")
|
||
if old_facility_refs > 0:
|
||
print(f" 🔄 Updating {old_facility_refs} facility FK reference(s)...")
|
||
content = content.replace(f"'{app_name}.Facility'", "'core.Facility'")
|
||
changes_made = True
|
||
|
||
# Step 5: Write changes if any were made
|
||
if changes_made:
|
||
models_path.write_text(content, encoding='utf-8')
|
||
print(f" ✅ {app_name}/models.py updated successfully!")
|
||
return True
|
||
else:
|
||
print(f" ℹ️ No changes needed for {app_name}/models.py")
|
||
return False
|
||
|
||
def main():
|
||
"""Main function to update all apps."""
|
||
|
||
print("=" * 70)
|
||
print("UPDATING ALL APPS TO USE CORE MODELS")
|
||
print("=" * 70)
|
||
|
||
updated_count = 0
|
||
skipped_count = 0
|
||
|
||
for app_name, changes_needed in APPS_TO_UPDATE.items():
|
||
result = update_app_models(app_name, changes_needed)
|
||
if result:
|
||
updated_count += 1
|
||
else:
|
||
skipped_count += 1
|
||
|
||
print("\n" + "=" * 70)
|
||
print("SUMMARY")
|
||
print("=" * 70)
|
||
print(f"✅ Apps updated: {updated_count}")
|
||
print(f"ℹ️ Apps skipped: {skipped_count}")
|
||
print(f"📊 Total apps processed: {len(APPS_TO_UPDATE)}")
|
||
|
||
print("\n" + "=" * 70)
|
||
print("NEXT STEPS")
|
||
print("=" * 70)
|
||
print("1. Review the changes in each app's models.py")
|
||
print("2. Check for any manual adjustments needed")
|
||
print("3. Delete db.sqlite3")
|
||
print("4. Delete all migration files (keep __init__.py)")
|
||
print("5. Run: python manage.py makemigrations")
|
||
print("6. Run: python manage.py migrate")
|
||
print("7. Create superuser")
|
||
print("8. Reseed data")
|
||
print("=" * 70)
|
||
|
||
return True
|
||
|
||
if __name__ == '__main__':
|
||
success = main()
|
||
sys.exit(0 if success else 1)
|