Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/services/mwl/c_find.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,15 @@ def call(self, event: evt.Event) -> Iterator[Tuple[int, Dataset | None]]:
logger.info(f"C-FIND request from {requestor_aet}")

query_patient_id = identifier.get("PatientID")
anonymised_patient_id = f"*******{query_patient_id[7:]}" if query_patient_id else "None"

procedure_sequence = identifier.get("ScheduledProcedureStepSequence", [{}])
query_modality = procedure_sequence[0].get("Modality")
query_date = procedure_sequence[0].get("ScheduledProcedureStepStartDate")

logger.debug(
"Query parameters: modality=%s, date=%s, patient_id=%s", query_modality, query_date, anonymised_patient_id
)
query_accession_number = identifier.get("AccessionNumber")

try:
items = self.storage.find_worklist_items(
accession_number=query_accession_number if query_accession_number else None,
modality=query_modality if query_modality else None,
scheduled_date=query_date if query_date else None,
patient_id=query_patient_id if query_patient_id else None,
Expand Down
6 changes: 6 additions & 0 deletions src/services/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ def store_worklist_item(

def find_worklist_items(
self,
accession_number: Optional[str] = None,
modality: Optional[str] = None,
scheduled_date: Optional[str] = None,
patient_id: Optional[str] = None,
Expand All @@ -372,6 +373,7 @@ def find_worklist_items(
Query worklist items with optional filters.

Args:
accession_number: Filter by accession number
modality: Filter by modality (e.g., "MG")
scheduled_date: Filter by scheduled date (YYYYMMDD)
patient_id: Filter by patient ID
Expand All @@ -388,6 +390,10 @@ def find_worklist_items(
where_clauses = []
params = []

if accession_number:
where_clauses.append("accession_number = ?")
params.append(accession_number)

if modality:
where_clauses.append("modality = ?")
params.append(modality)
Expand Down
17 changes: 17 additions & 0 deletions tests/integration/test_c_find_returns_worklist_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,23 @@ def test_cfind_filters_by_scheduled_date(self, event, storage):
assert status == SUCCESS
assert ds is None

def test_cfind_filters_by_accession_number(self, event, storage):
event.identifier.AccessionNumber = "ACC234567"

results = list(CFind(storage).call(event))

assert len(results) == 2

status, ds = results[0]
assert status == PENDING
assert ds.PatientID == "999234567"
assert ds.PatientName == "JONES^MARY"
assert ds.AccessionNumber == "ACC234567"

status, ds = results[1]
assert status == SUCCESS
assert ds is None

def test_cfind_filters_by_modality(self, event, storage):
storage.store_worklist_item(
WorklistItem(
Expand Down
18 changes: 15 additions & 3 deletions tests/services/mwl/test_c_find.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ def test_call_with_multiple_results(self, handler, mock_storage, mock_event):
status, ds = results[3]
assert status == SUCCESS

def test_call_with_accession_number_filter(self, handler, mock_storage, mock_event):
mock_event.identifier.AccessionNumber = "ACC12345"
mock_storage.find_worklist_items.return_value = []

list(handler.call(mock_event))

mock_storage.find_worklist_items.assert_called_once_with(
accession_number="ACC12345", modality=None, scheduled_date=None, patient_id=None
)

def test_call_with_modality_filter(self, handler, mock_storage, mock_event):
# Add modality to query
sps_item = Dataset()
Expand All @@ -116,7 +126,9 @@ def test_call_with_modality_filter(self, handler, mock_storage, mock_event):

list(handler.call(mock_event))

mock_storage.find_worklist_items.assert_called_once_with(modality="MG", scheduled_date=None, patient_id=None)
mock_storage.find_worklist_items.assert_called_once_with(
accession_number=None, modality="MG", scheduled_date=None, patient_id=None
)

def test_call_with_date_filter(self, handler, mock_storage, mock_event):
sps_item = Dataset()
Expand All @@ -127,7 +139,7 @@ def test_call_with_date_filter(self, handler, mock_storage, mock_event):
list(handler.call(mock_event))

mock_storage.find_worklist_items.assert_called_once_with(
modality=None, scheduled_date="20260107", patient_id=None
accession_number=None, modality=None, scheduled_date="20260107", patient_id=None
)

def test_call_with_patient_id_filter(self, handler, mock_storage, mock_event):
Expand All @@ -137,7 +149,7 @@ def test_call_with_patient_id_filter(self, handler, mock_storage, mock_event):
list(handler.call(mock_event))

mock_storage.find_worklist_items.assert_called_once_with(
modality=None, scheduled_date=None, patient_id="9876543210"
accession_number=None, modality=None, scheduled_date=None, patient_id="9876543210"
)

def test_call_handles_storage_exception(self, handler, mock_storage, mock_event):
Expand Down
57 changes: 25 additions & 32 deletions tests/services/test_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,16 @@ def test_find_worklist_items(self, mock_db, tmp_dir, result):
assert len(results) == 1
assert results[0] == WorklistItem(**result)

def test_find_worklist_items_with_filters(self, mock_db, tmp_dir):
@pytest.mark.parametrize(
"query_param_name, query_param_value",
[
("accession_number", "ACC123456"),
("patient_id", "999123456"),
("modality", "CT"),
("scheduled_date", "20240101"),
],
)
def test_find_worklist_items_with_filters(self, mock_db, tmp_dir, query_param_name, query_param_value):
mock_cursor = MagicMock()
mock_cursor.fetchall.return_value = []
mock_connection = MagicMock()
Expand All @@ -229,58 +238,42 @@ def test_find_worklist_items_with_filters(self, mock_db, tmp_dir):
subject = MWLStorage(tmp_dir)
mock_connection.reset_mock()

subject.find_worklist_items(patient_id="999123456")
find_args = {query_param_name: query_param_value}
subject.find_worklist_items(**find_args)

mock_connection.execute.assert_called_once_with(
(
"SELECT accession_number, modality, patient_birth_date, patient_id, "
"patient_name, patient_sex, procedure_code, scheduled_date, scheduled_time, "
"source_message_id, study_description, study_instance_uid, status, mpps_instance_uid "
"FROM worklist_items WHERE patient_id = ? ORDER BY scheduled_date, scheduled_time"
f"FROM worklist_items WHERE {query_param_name} = ? ORDER BY scheduled_date, scheduled_time"
),
["999123456"],
[query_param_value],
)

mock_connection.reset_mock()
subject.find_worklist_items(modality="CT")

mock_connection.execute.assert_called_once_with(
(
"SELECT accession_number, modality, patient_birth_date, patient_id, "
"patient_name, patient_sex, procedure_code, scheduled_date, scheduled_time, "
"source_message_id, study_description, study_instance_uid, status, mpps_instance_uid "
"FROM worklist_items WHERE modality = ? ORDER BY scheduled_date, scheduled_time"
),
["CT"],
)
def test_find_worklist_items_with_multiple_filters(self, mock_db, tmp_dir):
mock_cursor = MagicMock()
mock_cursor.fetchall.return_value = []
mock_connection = MagicMock()
mock_connection.execute.return_value = mock_cursor
mock_db.connect.return_value = mock_connection

subject = MWLStorage(tmp_dir)
mock_connection.reset_mock()
subject.find_worklist_items(scheduled_date="20240101")

mock_connection.execute.assert_called_once_with(
(
"SELECT accession_number, modality, patient_birth_date, patient_id, "
"patient_name, patient_sex, procedure_code, scheduled_date, scheduled_time, "
"source_message_id, study_description, study_instance_uid, status, mpps_instance_uid "
"FROM worklist_items WHERE scheduled_date = ? "
"ORDER BY scheduled_date, scheduled_time"
),
["20240101"],
subject.find_worklist_items(
accession_number="ACC123456", modality="MG", scheduled_date="20240101", patient_id="999123456"
)

mock_connection.reset_mock()
subject.find_worklist_items(modality="MG", scheduled_date="20240101", patient_id="999123456")

mock_connection.execute.assert_called_once_with(
(
"SELECT accession_number, modality, patient_birth_date, patient_id, "
"patient_name, patient_sex, procedure_code, scheduled_date, scheduled_time, "
"source_message_id, study_description, study_instance_uid, status, mpps_instance_uid "
"FROM worklist_items "
"WHERE modality = ? AND scheduled_date = ? AND patient_id = ? "
"WHERE accession_number = ? AND modality = ? AND scheduled_date = ? AND patient_id = ? "
"ORDER BY scheduled_date, scheduled_time"
),
["MG", "20240101", "999123456"],
["ACC123456", "MG", "20240101", "999123456"],
)

def test_get_worklist_item(self, mock_db, tmp_dir, result):
Expand Down
Loading