""" Django management command to populate Saudi insurance providers and create sample patients. Usage: python manage.py populate_saudi_insurance --tenant-id 1 python manage.py populate_saudi_insurance --create-patients 50 """ from django.core.management.base import BaseCommand, CommandError from django.contrib.auth import get_user_model from django.db import transaction from django.utils import timezone from patients.models import PatientProfile, InsuranceInfo from patients.data_generators.saudi_claims_generator import SaudiClaimsDataGenerator from core.models import Tenant import random from datetime import datetime, timedelta User = get_user_model() class Command(BaseCommand): help = 'Populate Saudi insurance providers and create sample patients with insurance' def add_arguments(self, parser): parser.add_argument( '--tenant-id', type=int, required=True, help='Tenant ID to create data for' ) parser.add_argument( '--create-patients', type=int, default=20, help='Number of patients to create (default: 20)' ) parser.add_argument( '--dry-run', action='store_true', help='Show what would be created without creating records' ) def handle(self, *args, **options): """Main command handler.""" try: # Get tenant tenant = Tenant.objects.get(id=options['tenant_id']) if options['dry_run']: self._dry_run(tenant, options) else: self._create_data(tenant, options) except Tenant.DoesNotExist: raise CommandError(f"Tenant with ID {options['tenant_id']} not found") except Exception as e: raise CommandError(f"Error: {str(e)}") def _dry_run(self, tenant, options): """Show what would be created.""" self.stdout.write( self.style.WARNING("DRY RUN - No records will be created") ) generator = SaudiClaimsDataGenerator() self.stdout.write(f"\nWould create for tenant: {tenant.name}") self.stdout.write(f"Number of patients: {options['create_patients']}") self.stdout.write(f"Insurance companies available: {len(generator.SAUDI_INSURANCE_COMPANIES)}") # Show sample data self.stdout.write(f"\nSample insurance companies:") for company in generator.SAUDI_INSURANCE_COMPANIES[:5]: self.stdout.write(f" - {company}") self.stdout.write(f"\nSample patient names:") for i in range(3): male_name = f"{random.choice(generator.SAUDI_FIRST_NAMES_MALE)} {random.choice(generator.SAUDI_FAMILY_NAMES)}" female_name = f"{random.choice(generator.SAUDI_FIRST_NAMES_FEMALE)} {random.choice(generator.SAUDI_FAMILY_NAMES)}" self.stdout.write(f" - {male_name}") self.stdout.write(f" - {female_name}") def _create_data(self, tenant, options): """Create the actual data.""" generator = SaudiClaimsDataGenerator() created_by = self._get_system_user() self.stdout.write(f"Creating data for tenant: {tenant.name}") patients_created = 0 insurance_created = 0 with transaction.atomic(): # Create patients with insurance for i in range(options['create_patients']): try: # Generate patient data is_male = random.choice([True, False]) if is_male: first_name = random.choice(generator.SAUDI_FIRST_NAMES_MALE) gender = 'M' else: first_name = random.choice(generator.SAUDI_FIRST_NAMES_FEMALE) gender = 'F' last_name = random.choice(generator.SAUDI_FAMILY_NAMES) # Generate birth date (18-80 years old) birth_date = datetime.now().date() - timedelta( days=random.randint(18*365, 80*365) ) # Create patient patient = PatientProfile.objects.create( tenant=tenant, mrn=f"MRN{random.randint(100000, 999999)}", first_name=first_name, last_name=last_name, date_of_birth=birth_date, gender=gender, phone_number=f"+966{random.randint(500000000, 599999999)}", email=f"{first_name.lower()}.{last_name.lower().replace(' ', '')}@example.com", address=f"الرياض، المملكة العربية السعودية", city="الرياض", country="SA", created_by=created_by ) patients_created += 1 # Create 1-2 insurance policies per patient num_insurances = random.choices([1, 2], weights=[0.7, 0.3])[0] for j in range(num_insurances): insurance_company = random.choice(generator.SAUDI_INSURANCE_COMPANIES) # Generate policy dates effective_date = datetime.now().date() - timedelta( days=random.randint(30, 365) ) expiration_date = effective_date + timedelta(days=365) # Create insurance insurance = InsuranceInfo.objects.create( patient=patient, insurance_type='PRIMARY' if j == 0 else 'SECONDARY', insurance_company=insurance_company, plan_name=f"{insurance_company.split()[0]} Premium Plan", plan_type=random.choice(['HMO', 'PPO', 'EPO']), policy_number=f"POL{random.randint(100000000, 999999999)}", member_id=f"MEM{random.randint(100000000, 999999999)}", group_number=f"GRP{random.randint(10000, 99999)}", effective_date=effective_date, expiration_date=expiration_date, copay=random.choice([50, 75, 100, 150, 200]), deductible=random.choice([500, 1000, 1500, 2000, 2500]), subscriber_name=patient.get_full_name(), subscriber_relationship='SELF', subscriber_dob=patient.date_of_birth, created_by=created_by ) insurance_created += 1 if (i + 1) % 10 == 0: self.stdout.write(f"Created {i + 1} patients...") except Exception as e: self.stdout.write( self.style.ERROR(f"Error creating patient {i + 1}: {str(e)}") ) continue # Show results self.stdout.write( self.style.SUCCESS( f"Successfully created {patients_created} patients and {insurance_created} insurance policies" ) ) # Show sample data sample_patients = PatientProfile.objects.filter(tenant=tenant).order_by('-created_at')[:5] if sample_patients: self.stdout.write(f"\nSample created patients:") for patient in sample_patients: insurance_count = patient.insurance_info.count() self.stdout.write( f" - {patient.get_full_name()} (MRN: {patient.mrn}, Insurance policies: {insurance_count})" ) # Show insurance companies used used_companies = InsuranceInfo.objects.filter( patient__tenant=tenant ).values_list('insurance_company', flat=True).distinct() self.stdout.write(f"\nInsurance companies used ({len(used_companies)}):") for company in sorted(used_companies)[:10]: self.stdout.write(f" - {company}") if len(used_companies) > 10: self.stdout.write(f" ... and {len(used_companies) - 10} more") def _get_system_user(self): """Get or create a system user for created_by field.""" try: return User.objects.get(username='system') except User.DoesNotExist: # Try to get the first superuser superuser = User.objects.filter(is_superuser=True).first() if superuser: return superuser # Try to get any user user = User.objects.first() if user: return user # Create a system user if none exists return User.objects.create_user( username='system', email='system@hospital.local', first_name='System', last_name='Generator', is_active=True )