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