Skip to content

Commit e34a187

Browse files
committed
added filters for logged FIT kits and kit notes
1 parent 0cfd2b5 commit e34a187

File tree

3 files changed

+132
-36
lines changed

3 files changed

+132
-36
lines changed

utils/oracle/mock_selection_builder.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,35 +36,35 @@ def dump_sql(self):
3636
# Replace this with the one you want to test,
3737
# then use utils/oracle/test_subject_criteria_dev.py to run your scenarios
3838

39-
def _add_criteria_has_diagnostic_test_containing_polyp(self) -> None:
39+
def _add_criteria_subject_has_kit_notes(self) -> None:
4040
"""
41-
Adds logic to filter based on whether a diagnostic test has a recorded polyp.
42-
'Yes' joins polyp tables; 'No' checks for absence via NOT EXISTS.
41+
Filters subjects based on presence of active kit-related notes.
42+
Accepts values: 'yes' or 'no'.
4343
"""
4444
try:
4545
value = self.criteria_value.strip().lower()
4646

4747
if value == "yes":
48-
self.sql_from.append(
49-
"INNER JOIN external_tests_t ext ON ep.subject_epis_id = ext.subject_epis_id\n"
50-
"INNER JOIN ds_colonoscopy_t dsc ON ext.ext_test_id = dsc.ext_test_id\n"
51-
"INNER JOIN ds_polyp_t dst ON ext.ext_test_id = dst.ext_test_id"
52-
)
53-
self.sql_where.append(
54-
"AND ext.void = 'N'\n"
55-
"AND dst.deleted_flag = 'N'"
56-
)
48+
prefix = "AND EXISTS"
5749
elif value == "no":
58-
self.sql_where.append(
59-
"""AND NOT EXISTS (
60-
SELECT 'ext'
61-
FROM external_tests_t ext
62-
LEFT JOIN ds_polyp_t dst ON ext.ext_test_id = dst.ext_test_id
63-
WHERE ext.subject_epis_id = ep.subject_epis_id
64-
)"""
65-
)
50+
prefix = "AND NOT EXISTS"
6651
else:
67-
raise ValueError(f"Unknown value for diagnostic test containing polyp: {value}")
52+
raise ValueError(f"Invalid value for kit notes: {value}")
53+
54+
self.sql_where.append(
55+
f"""{prefix} (
56+
SELECT 1
57+
FROM supporting_notes_t sn
58+
WHERE sn.screening_subject_id = ss.screening_subject_id
59+
AND (
60+
sn.type_id = '308015'
61+
OR sn.promote_pio_id IS NOT NULL
62+
)
63+
AND sn.status_id = 4100
64+
)
65+
AND ss.number_of_invitations > 0
66+
AND rownum = 1"""
67+
)
6868

6969
except Exception:
7070
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)

utils/oracle/subject_selection_query_builder.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ def _add_variable_selection_criteria(
390390
SubjectSelectionCriteriaKey.HAS_DIAGNOSTIC_TEST_CONTAINING_POLYP
391391
):
392392
self._add_criteria_has_diagnostic_test_containing_polyp()
393+
# ------------------------------------------------------------------------
394+
# 📦 Kit Metadata & Participation History
395+
# ------------------------------------------------------------------------
393396
case SubjectSelectionCriteriaKey.SUBJECT_HAS_UNLOGGED_KITS:
394397
self._add_criteria_subject_has_unlogged_kits()
395398
case SubjectSelectionCriteriaKey.SUBJECT_HAS_LOGGED_FIT_KITS:
@@ -1261,6 +1264,104 @@ def _add_criteria_has_diagnostic_test_containing_polyp(self) -> None:
12611264
except Exception:
12621265
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
12631266

1267+
def _add_criteria_subject_has_unlogged_kits(self) -> None:
1268+
"""
1269+
Adds a filter to check for unlogged kits across subject history,
1270+
or scoped to the latest episode. Accepts:
1271+
- "yes"
1272+
- "yes_latest_episode"
1273+
- "no"
1274+
"""
1275+
try:
1276+
value = self.criteria_value.strip().lower()
1277+
1278+
if value in ("yes", "yes_latest_episode"):
1279+
prefix = "AND EXISTS"
1280+
elif value == "no":
1281+
prefix = "AND NOT EXISTS"
1282+
else:
1283+
raise ValueError(f"Unknown value for unlogged kits: {value}")
1284+
1285+
subquery = [
1286+
f"{prefix} (",
1287+
" SELECT 'tku'",
1288+
" FROM tk_items_t tku",
1289+
" WHERE tku.screening_subject_id = ss.screening_subject_id",
1290+
]
1291+
1292+
if value == "yes_latest_episode":
1293+
self._add_join_to_latest_episode()
1294+
subquery.append(" AND tku.subject_epis_id = ep.subject_epis_id")
1295+
1296+
subquery.append(" AND tku.logged_in_flag = 'N'")
1297+
subquery.append(")")
1298+
1299+
self.sql_where.append("\n".join(subquery))
1300+
1301+
except Exception:
1302+
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
1303+
1304+
def _add_criteria_subject_has_logged_fit_kits(self) -> None:
1305+
"""
1306+
Adds a filter to check if the subject has logged FIT kits (tk_type_id > 1 and logged_in_flag = 'Y').
1307+
Accepts values: 'yes' or 'no'.
1308+
"""
1309+
try:
1310+
value = self.criteria_value.strip().lower()
1311+
1312+
if value == "yes":
1313+
prefix = "AND EXISTS"
1314+
elif value == "no":
1315+
prefix = "AND NOT EXISTS"
1316+
else:
1317+
raise ValueError(f"Invalid value for logged FIT kits: {value}")
1318+
1319+
self.sql_where.append(
1320+
f"""{prefix} (
1321+
SELECT 'tkl'
1322+
FROM tk_items_t tkl
1323+
WHERE tkl.screening_subject_id = ss.screening_subject_id
1324+
AND tkl.tk_type_id > 1
1325+
AND tkl.logged_in_flag = 'Y'
1326+
)"""
1327+
)
1328+
1329+
except Exception:
1330+
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
1331+
1332+
def _add_criteria_subject_has_kit_notes(self) -> None:
1333+
"""
1334+
Filters subjects based on presence of active kit-related notes.
1335+
Accepts values: 'yes' or 'no'.
1336+
"""
1337+
try:
1338+
value = self.criteria_value.strip().lower()
1339+
1340+
if value == "yes":
1341+
prefix = "AND EXISTS"
1342+
elif value == "no":
1343+
prefix = "AND NOT EXISTS"
1344+
else:
1345+
raise ValueError(f"Invalid value for kit notes: {value}")
1346+
1347+
self.sql_where.append(
1348+
f"""{prefix} (
1349+
SELECT 1
1350+
FROM supporting_notes_t sn
1351+
WHERE sn.screening_subject_id = ss.screening_subject_id
1352+
AND (
1353+
sn.type_id = '308015'
1354+
OR sn.promote_pio_id IS NOT NULL
1355+
)
1356+
AND sn.status_id = 4100
1357+
)
1358+
AND ss.number_of_invitations > 0
1359+
AND rownum = 1"""
1360+
)
1361+
1362+
except Exception:
1363+
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
1364+
12641365
def _add_criteria_subject_hub_code(self, user: "User") -> None:
12651366
hub_code = None
12661367
try:

utils/oracle/test_subject_criteria_dev.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,18 @@
2525
print("PYTHONPATH set to:", sys.path[0])
2626
from mock_selection_builder import MockSelectionBuilder
2727
from classes.subject_selection_criteria_key import SubjectSelectionCriteriaKey
28-
from classes.episode_type import EpisodeType # Add this for the third test
2928

3029
# === Example usage ===
31-
# Replace the examples below with the method you want to test
32-
33-
# === Test: HAS_DIAGNOSTIC_TEST_CONTAINING_POLYP — yes ===
34-
builder = MockSelectionBuilder(
35-
SubjectSelectionCriteriaKey.HAS_DIAGNOSTIC_TEST_CONTAINING_POLYP, "yes"
36-
)
37-
builder._add_criteria_has_diagnostic_test_containing_polyp()
38-
print("=== HAS_DIAGNOSTIC_TEST_CONTAINING_POLYP — yes ===")
30+
# Replace the examples below with your tests for the method you want to test
31+
32+
# === Test: SUBJECT_HAS_KIT_NOTES — yes ===
33+
builder = MockSelectionBuilder(SubjectSelectionCriteriaKey.SUBJECT_HAS_KIT_NOTES, "yes")
34+
builder._add_criteria_subject_has_kit_notes()
35+
print("=== SUBJECT_HAS_KIT_NOTES — yes ===")
3936
print(builder.dump_sql(), end="\n\n")
4037

41-
# === Test: HAS_DIAGNOSTIC_TEST_CONTAINING_POLYP — no ===
42-
builder = MockSelectionBuilder(
43-
SubjectSelectionCriteriaKey.HAS_DIAGNOSTIC_TEST_CONTAINING_POLYP, "no"
44-
)
45-
builder._add_criteria_has_diagnostic_test_containing_polyp()
46-
print("=== HAS_DIAGNOSTIC_TEST_CONTAINING_POLYP — no ===")
38+
# === Test: SUBJECT_HAS_KIT_NOTES — no ===
39+
builder = MockSelectionBuilder(SubjectSelectionCriteriaKey.SUBJECT_HAS_KIT_NOTES, "no")
40+
builder._add_criteria_subject_has_kit_notes()
41+
print("=== SUBJECT_HAS_KIT_NOTES — no ===")
4742
print(builder.dump_sql(), end="\n\n")

0 commit comments

Comments
 (0)