refactor matching algo
Browse files- utils/oneclick.py +8 -11
- utils/responseparser.py +10 -2
utils/oneclick.py
CHANGED
|
@@ -4,6 +4,7 @@ from .meldrx import MeldRxAPI
|
|
| 4 |
from .responseparser import PatientDataExtractor
|
| 5 |
from .pdfutils import PDFGenerator
|
| 6 |
import logging
|
|
|
|
| 7 |
|
| 8 |
logger = logging.getLogger(__name__)
|
| 9 |
|
|
@@ -54,12 +55,6 @@ def generate_discharge_paper_one_click(
|
|
| 54 |
first_name: str = "",
|
| 55 |
last_name: str = ""
|
| 56 |
) -> Tuple[Optional[str], str, Optional[str], Optional[str]]:
|
| 57 |
-
"""
|
| 58 |
-
Generate a discharge summary PDF with one click using MeldRx API data.
|
| 59 |
-
|
| 60 |
-
Returns:
|
| 61 |
-
Tuple of (pdf_path, status_message, basic_summary, ai_summary)
|
| 62 |
-
"""
|
| 63 |
try:
|
| 64 |
patients_data = api.get_patients()
|
| 65 |
if not patients_data or "entry" not in patients_data:
|
|
@@ -89,7 +84,7 @@ def generate_discharge_paper_one_click(
|
|
| 89 |
last_name_from_data = str(patient_data.get('last_name', '')).strip().lower()
|
| 90 |
|
| 91 |
all_patient_ids.append(patient_id_from_data)
|
| 92 |
-
all_patient_names.append(f"{first_name_from_data} {last_name_from_data}")
|
| 93 |
|
| 94 |
patient_id_input = str(patient_id).strip().lower()
|
| 95 |
first_name_input = str(first_name).strip().lower()
|
|
@@ -99,11 +94,13 @@ def generate_discharge_paper_one_click(
|
|
| 99 |
logger.debug(f"Comparing - Input: ID={patient_id_input}, First={first_name_input}, Last={last_name_input}")
|
| 100 |
|
| 101 |
matches = True
|
| 102 |
-
if
|
|
|
|
| 103 |
matches = False
|
| 104 |
-
|
|
|
|
| 105 |
matches = False
|
| 106 |
-
if last_name_input and last_name_input
|
| 107 |
matches = False
|
| 108 |
|
| 109 |
if matches:
|
|
@@ -119,7 +116,7 @@ def generate_discharge_paper_one_click(
|
|
| 119 |
return None, (f"No patients found matching criteria: {search_criteria}\n"
|
| 120 |
f"Available IDs: {', '.join(all_patient_ids)}\n"
|
| 121 |
f"Available Names: {', '.join(all_patient_names)}"), None, None
|
| 122 |
-
|
| 123 |
patient_data = matching_patients[0]
|
| 124 |
logger.info(f"Selected patient data: {patient_data}")
|
| 125 |
|
|
|
|
| 4 |
from .responseparser import PatientDataExtractor
|
| 5 |
from .pdfutils import PDFGenerator
|
| 6 |
import logging
|
| 7 |
+
import json
|
| 8 |
|
| 9 |
logger = logging.getLogger(__name__)
|
| 10 |
|
|
|
|
| 55 |
first_name: str = "",
|
| 56 |
last_name: str = ""
|
| 57 |
) -> Tuple[Optional[str], str, Optional[str], Optional[str]]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
try:
|
| 59 |
patients_data = api.get_patients()
|
| 60 |
if not patients_data or "entry" not in patients_data:
|
|
|
|
| 84 |
last_name_from_data = str(patient_data.get('last_name', '')).strip().lower()
|
| 85 |
|
| 86 |
all_patient_ids.append(patient_id_from_data)
|
| 87 |
+
all_patient_names.append(f"{first_name_from_data} {last_name_from_data}".strip())
|
| 88 |
|
| 89 |
patient_id_input = str(patient_id).strip().lower()
|
| 90 |
first_name_input = str(first_name).strip().lower()
|
|
|
|
| 94 |
logger.debug(f"Comparing - Input: ID={patient_id_input}, First={first_name_input}, Last={last_name_input}")
|
| 95 |
|
| 96 |
matches = True
|
| 97 |
+
# Only enforce ID match if both input and data have non-empty IDs
|
| 98 |
+
if patient_id_input and patient_id_from_data and patient_id_input != patient_id_from_data:
|
| 99 |
matches = False
|
| 100 |
+
# Use exact match for names if provided, ignoring case
|
| 101 |
+
if first_name_input and first_name_input != first_name_from_data:
|
| 102 |
matches = False
|
| 103 |
+
if last_name_input and last_name_input != last_name_from_data:
|
| 104 |
matches = False
|
| 105 |
|
| 106 |
if matches:
|
|
|
|
| 116 |
return None, (f"No patients found matching criteria: {search_criteria}\n"
|
| 117 |
f"Available IDs: {', '.join(all_patient_ids)}\n"
|
| 118 |
f"Available Names: {', '.join(all_patient_names)}"), None, None
|
| 119 |
+
logger.debug(f"Raw patient data from API: {json.dumps(patients_data, indent=2)}")
|
| 120 |
patient_data = matching_patients[0]
|
| 121 |
logger.info(f"Selected patient data: {patient_data}")
|
| 122 |
|
utils/responseparser.py
CHANGED
|
@@ -59,14 +59,22 @@ class PatientDataExtractor:
|
|
| 59 |
"""Get the currently selected patient resource."""
|
| 60 |
return self.patients[self.current_patient_idx]
|
| 61 |
|
| 62 |
-
# Basic Identification Fields
|
| 63 |
def get_id(self) -> str:
|
| 64 |
patient = self._get_current_patient()
|
| 65 |
if self.format == "xml":
|
| 66 |
id_list = patient.xpath("//hl7:recordTarget/hl7:patientRole/hl7:id/@extension", namespaces=self.ns)
|
| 67 |
return id_list[0] if id_list else ""
|
| 68 |
elif self.format == "json":
|
| 69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
def get_resource_type(self) -> str:
|
| 72 |
patient = self._get_current_patient()
|
|
|
|
| 59 |
"""Get the currently selected patient resource."""
|
| 60 |
return self.patients[self.current_patient_idx]
|
| 61 |
|
|
|
|
| 62 |
def get_id(self) -> str:
|
| 63 |
patient = self._get_current_patient()
|
| 64 |
if self.format == "xml":
|
| 65 |
id_list = patient.xpath("//hl7:recordTarget/hl7:patientRole/hl7:id/@extension", namespaces=self.ns)
|
| 66 |
return id_list[0] if id_list else ""
|
| 67 |
elif self.format == "json":
|
| 68 |
+
# Check top-level 'id' first
|
| 69 |
+
patient_id = patient.get("id", "")
|
| 70 |
+
if patient_id:
|
| 71 |
+
return patient_id
|
| 72 |
+
# Fallback to 'identifier' field
|
| 73 |
+
identifiers = patient.get("identifier", [])
|
| 74 |
+
for identifier in identifiers:
|
| 75 |
+
if identifier.get("value"): # Return the first non-empty identifier value
|
| 76 |
+
return identifier["value"]
|
| 77 |
+
return "" # Default to empty string if no ID found
|
| 78 |
|
| 79 |
def get_resource_type(self) -> str:
|
| 80 |
patient = self._get_current_patient()
|