HH/apps/integrations/management/commands/fetch_his_surveys.py
2026-03-09 16:10:24 +03:00

183 lines
7.0 KiB
Python

"""
Management command to manually fetch surveys from HIS system.
Usage:
python manage.py fetch_his_surveys [--minutes N] [--limit N] [--test]
Options:
--minutes N Fetch patients discharged in the last N minutes (default: 10)
--limit N Maximum number of patients to fetch (default: 100)
--test Test connection only, don't fetch surveys
"""
from django.core.management.base import BaseCommand
from django.utils import timezone
from apps.integrations.services.his_client import HISClient, HISClientFactory
from apps.integrations.services.his_adapter import HISAdapter
class Command(BaseCommand):
help = 'Fetch surveys from HIS system'
def add_arguments(self, parser):
parser.add_argument(
'--minutes',
type=int,
default=10,
help='Fetch patients discharged in the last N minutes (default: 10)'
)
parser.add_argument(
'--limit',
type=int,
default=100,
help='Maximum number of patients to fetch (default: 100)'
)
parser.add_argument(
'--test',
action='store_true',
help='Test connection only, don\'t fetch surveys'
)
parser.add_argument(
'--config',
type=str,
help='Configuration name to use (optional)'
)
def handle(self, *args, **options):
minutes = options['minutes']
limit = options['limit']
test_only = options['test']
config_name = options.get('config')
self.stdout.write(self.style.MIGRATE_HEADING('=' * 70))
self.stdout.write(self.style.MIGRATE_HEADING('HIS Survey Fetch'))
self.stdout.write(self.style.MIGRATE_HEADING('=' * 70))
# Get clients
if config_name:
from apps.integrations.models import IntegrationConfig, SourceSystem
config = IntegrationConfig.objects.filter(
name=config_name,
source_system=SourceSystem.HIS
).first()
if not config:
self.stdout.write(
self.style.ERROR(f'Configuration "{config_name}" not found')
)
return
clients = [HISClient(config)]
else:
clients = HISClientFactory.get_all_active_clients()
if not clients:
self.stdout.write(
self.style.ERROR('No active HIS configurations found')
)
return
self.stdout.write(f'Found {len(clients)} HIS configuration(s)')
total_patients = 0
total_surveys_created = 0
total_surveys_sent = 0
for client in clients:
config_display = client.config.name if client.config else 'Default'
self.stdout.write(self.style.MIGRATE_HEADING(f'\n📡 Configuration: {config_display}'))
# Test connection
self.stdout.write('Testing connection...', ending=' ')
test_result = client.test_connection()
if test_result['success']:
self.stdout.write(self.style.SUCCESS('✓ Connected'))
else:
self.stdout.write(
self.style.ERROR(f'✗ Failed: {test_result["message"]}')
)
continue
if test_only:
continue
# Calculate fetch window
from datetime import timedelta
fetch_since = timezone.now() - timedelta(minutes=minutes)
self.stdout.write(
f'Fetching discharged patients since {fetch_since.strftime("%Y-%m-%d %H:%M:%S")}...'
)
# Fetch patients
patients = client.fetch_discharged_patients(since=fetch_since, limit=limit)
if not patients:
self.stdout.write(self.style.WARNING('No patients found'))
continue
self.stdout.write(f'Found {len(patients)} patient(s)')
# Process each patient
for i, patient_data in enumerate(patients, 1):
self.stdout.write(f'\n Processing patient {i}/{len(patients)}...')
try:
# Ensure proper format
if isinstance(patient_data, dict):
if 'FetchPatientDataTimeStampList' not in patient_data:
patient_data = {
'FetchPatientDataTimeStampList': [patient_data],
'FetchPatientDataTimeStampVisitDataList': [],
'Code': 200,
'Status': 'Success'
}
# Process
result = HISAdapter.process_his_data(patient_data)
if result['success']:
total_surveys_created += 1
patient_name = "Unknown"
if result.get('patient'):
patient_name = f"{result['patient'].first_name} {result['patient'].last_name}".strip()
if result.get('survey_sent'):
total_surveys_sent += 1
self.stdout.write(
f' {self.style.SUCCESS("")} Survey sent to {patient_name}'
)
else:
self.stdout.write(
f' {self.style.WARNING("")} Survey created but not sent to {patient_name}'
)
else:
self.stdout.write(
f' {self.style.ERROR("")} {result.get("message", "Unknown error")}'
)
except Exception as e:
self.stdout.write(
f' {self.style.ERROR("")} Error: {str(e)}'
)
total_patients += len(patients)
# Update last sync
if client.config:
client.config.last_sync_at = timezone.now()
client.config.save(update_fields=['last_sync_at'])
# Summary
self.stdout.write(self.style.MIGRATE_HEADING('\n' + '=' * 70))
self.stdout.write(self.style.MIGRATE_HEADING('Summary'))
self.stdout.write(self.style.MIGRATE_HEADING('=' * 70))
self.stdout.write(f'Total patients fetched: {total_patients}')
self.stdout.write(f'Total surveys created: {total_surveys_created}')
self.stdout.write(f'Total surveys sent: {total_surveys_sent}')
if test_only:
self.stdout.write(self.style.SUCCESS('\nConnection test completed successfully!'))
else:
self.stdout.write(self.style.SUCCESS('\nFetch completed!'))