218 lines
7.2 KiB
Python
Executable File
218 lines
7.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
"""
|
|
Test script to diagnose staff matching issues.
|
|
|
|
This script helps identify why staff matching is failing for specific names.
|
|
"""
|
|
import os
|
|
import django
|
|
|
|
# Setup Django
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.dev')
|
|
django.setup()
|
|
|
|
from apps.organizations.models import Staff, Department, Hospital
|
|
|
|
|
|
def test_staff_exists():
|
|
"""Check if staff member exists in database."""
|
|
|
|
# Get first hospital
|
|
hospital = Hospital.objects.first()
|
|
if not hospital:
|
|
print("❌ No hospitals found in database")
|
|
return
|
|
|
|
print(f"\n🏥 Testing with hospital: {hospital.name} (ID: {hospital.id})")
|
|
print("=" * 80)
|
|
|
|
# Test names from the complaint
|
|
test_names = [
|
|
"ابراهيم عبد العزيز الشمري",
|
|
"Ibrahim Abdulaziz Al-Shammari"
|
|
]
|
|
|
|
for name in test_names:
|
|
print(f"\n🔍 Searching for: '{name}'")
|
|
print("-" * 80)
|
|
|
|
# Check all staff in hospital
|
|
all_staff = Staff.objects.filter(hospital=hospital, status='active')
|
|
print(f" Total active staff: {all_staff.count()}")
|
|
|
|
# Try exact matches
|
|
exact_matches = all_staff.filter(
|
|
first_name__iexact=name
|
|
) | all_staff.filter(
|
|
last_name__iexact=name
|
|
) | all_staff.filter(
|
|
first_name_ar__iexact=name
|
|
) | all_staff.filter(
|
|
last_name_ar__iexact=name
|
|
)
|
|
|
|
if exact_matches.exists():
|
|
print(f" ✅ Exact match found: {exact_matches.count()} staff")
|
|
for staff in exact_matches:
|
|
print_staff_details(staff)
|
|
else:
|
|
print(f" ❌ No exact match found")
|
|
|
|
# Try partial matches
|
|
partial_matches = all_staff.filter(
|
|
first_name__icontains=name
|
|
) | all_staff.filter(
|
|
last_name__icontains=name
|
|
) | all_staff.filter(
|
|
first_name_ar__icontains=name
|
|
) | all_staff.filter(
|
|
last_name_ar__icontains=name
|
|
)
|
|
|
|
if partial_matches.exists():
|
|
print(f" ⚠️ Partial match found: {partial_matches.count()} staff")
|
|
for staff in partial_matches[:5]: # Show first 5
|
|
print_staff_details(staff)
|
|
else:
|
|
print(f" ❌ No partial match found")
|
|
|
|
# Try word matches (for full names)
|
|
if ' ' in name:
|
|
words = name.split()
|
|
if len(words) >= 2:
|
|
print(f" 🔎 Checking word-by-word match...")
|
|
for word in words:
|
|
word_matches = all_staff.filter(
|
|
first_name__icontains=word
|
|
) | all_staff.filter(
|
|
last_name__icontains=word
|
|
) | all_staff.filter(
|
|
first_name_ar__icontains=word
|
|
) | all_staff.filter(
|
|
last_name_ar__icontains=word
|
|
)
|
|
if word_matches.exists():
|
|
print(f" ✅ Word '{word}' matches {word_matches.count()} staff")
|
|
for staff in word_matches[:3]: # Show first 3
|
|
print(f" - {staff.first_name} {staff.last_name}")
|
|
else:
|
|
print(f" ❌ Word '{word}' has no matches")
|
|
|
|
|
|
def print_staff_details(staff):
|
|
"""Print staff member details."""
|
|
print(f" 📋 Staff ID: {staff.id}")
|
|
print(f" Name EN: {staff.first_name} {staff.last_name}")
|
|
print(f" Name AR: {staff.first_name_ar} {staff.last_name_ar}")
|
|
print(f" Job Title: {staff.job_title}")
|
|
print(f" Department: {staff.department.name if staff.department else 'N/A'}")
|
|
print(f" Specialization: {staff.specialization or 'N/A'}")
|
|
|
|
|
|
def test_matching_function():
|
|
"""Test the actual matching function."""
|
|
from apps.complaints.tasks import match_staff_from_name
|
|
|
|
print("\n\n" + "=" * 80)
|
|
print("🧪 TESTING match_staff_from_name() FUNCTION")
|
|
print("=" * 80)
|
|
|
|
hospital = Hospital.objects.first()
|
|
if not hospital:
|
|
print("❌ No hospitals found")
|
|
return
|
|
|
|
test_names = [
|
|
"ابراهيم عبد العزيز الشمري",
|
|
"Ibrahim Abdulaziz Al-Shammari",
|
|
"Ibrahim Al-Shammari",
|
|
"Abdulaziz Al-Shammari"
|
|
]
|
|
|
|
for name in test_names:
|
|
print(f"\n🔍 Testing: '{name}'")
|
|
|
|
# Test with return_all=True
|
|
matches, confidence, method = match_staff_from_name(
|
|
staff_name=name,
|
|
hospital_id=str(hospital.id),
|
|
department_name=None,
|
|
return_all=True
|
|
)
|
|
|
|
if matches:
|
|
print(f" ✅ Found {len(matches)} match(es)")
|
|
print(f" Best confidence: {confidence:.2f}")
|
|
print(f" Method: {method}")
|
|
for i, match in enumerate(matches[:5], 1):
|
|
print(f" {i}. {match['name_en']} (confidence: {match['confidence']:.2f})")
|
|
if match['name_ar']:
|
|
print(f" AR: {match['name_ar']}")
|
|
print(f" Method: {match['matching_method']}")
|
|
else:
|
|
print(f" ❌ No matches found")
|
|
print(f" Confidence: {confidence:.2f}")
|
|
print(f" Method: {method}")
|
|
|
|
|
|
def test_arabic_name_variations():
|
|
"""Test different Arabic name formats."""
|
|
from apps.complaints.tasks import match_staff_from_name
|
|
|
|
print("\n\n" + "=" * 80)
|
|
print("🌙 TESTING ARABIC NAME VARIATIONS")
|
|
print("=" * 80)
|
|
|
|
hospital = Hospital.objects.first()
|
|
|
|
# Show some sample staff
|
|
sample_staff = Staff.objects.filter(
|
|
hospital=hospital,
|
|
status='active',
|
|
first_name_ar__isnull=False
|
|
).exclude(first_name_ar='')[:10]
|
|
|
|
if not sample_staff:
|
|
print("❌ No Arabic staff names found")
|
|
return
|
|
|
|
print(f"\n📋 Sample staff with Arabic names:")
|
|
for staff in sample_staff:
|
|
full_ar = f"{staff.first_name_ar} {staff.last_name_ar}".strip()
|
|
full_en = f"{staff.first_name} {staff.last_name}".strip()
|
|
print(f"\n AR: {full_ar}")
|
|
print(f" EN: {full_en}")
|
|
print(f" ID: {staff.id}")
|
|
|
|
# Try to match using full Arabic name
|
|
matches, confidence, method = match_staff_from_name(
|
|
staff_name=full_ar,
|
|
hospital_id=str(hospital.id),
|
|
return_all=True
|
|
)
|
|
|
|
if matches:
|
|
found = any(m['id'] == str(staff.id) for m in matches)
|
|
if found:
|
|
print(f" ✅ Matched! confidence: {confidence:.2f}, method: {method}")
|
|
else:
|
|
print(f" ⚠️ Found other matches but not self:")
|
|
for m in matches[:3]:
|
|
print(f" - {m['name_en']}")
|
|
else:
|
|
print(f" ❌ No matches found (this is a problem!)")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
print("\n" + "=" * 80)
|
|
print("🔍 STAFF MATCHING DIAGNOSTICS")
|
|
print("=" * 80)
|
|
|
|
test_staff_exists()
|
|
test_matching_function()
|
|
test_arabic_name_variations()
|
|
|
|
print("\n\n" + "=" * 80)
|
|
print("✅ Diagnostic complete")
|
|
print("=" * 80)
|