Skip to content

Commit 6f4d6a9

Browse files
committed
Added appointment type filter and AppointmentSlotType mapping class to selection builder
1 parent 94896e9 commit 6f4d6a9

File tree

4 files changed

+80
-66
lines changed

4 files changed

+80
-66
lines changed

classes/appointments_slot_type.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class AppointmentSlotType:
2+
"""
3+
Maps symbolic appointment slot types to their internal IDs.
4+
Extend as needed.
5+
"""
6+
7+
_mapping = {
8+
"clinic": 1001,
9+
"phone": 1002,
10+
"video": 1003,
11+
# Add more mappings here as needed
12+
}
13+
14+
@classmethod
15+
def get_id(cls, description: str) -> int:
16+
key = description.strip().lower()
17+
if key not in cls._mapping:
18+
raise ValueError(f"Unknown appointment slot type: {description}")
19+
return cls._mapping[key]

utils/oracle/mock_selection_builder.py

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@
66
from classes.selection_builder_exception import SelectionBuilderException
77

88

9+
# Add helper class stubs below
10+
class AppointmentSlotType:
11+
"""
12+
Mocked appointment slot type mapping for test purposes.
13+
Replace IDs with real values from production enum if needed.
14+
"""
15+
16+
_mapping = {
17+
"clinic": 1001,
18+
"phone": 1002,
19+
"video": 1003,
20+
}
21+
22+
@classmethod
23+
def get_id(cls, description: str) -> int:
24+
key = description.strip().lower()
25+
if key not in cls._mapping:
26+
raise ValueError(f"Unknown appointment slot type: {description}")
27+
return cls._mapping[key]
28+
29+
930
class MockSelectionBuilder:
1031
"""
1132
Lightweight test harness that mimics SubjectSelectionQueryBuilder behavior.
@@ -52,47 +73,21 @@ def _add_join_to_latest_episode(self) -> None:
5273
# Replace this with the one you want to test,
5374
# then use utils/oracle/test_subject_criteria_dev.py to run your scenarios
5475

55-
def _add_join_to_appointments(self) -> None:
76+
def _add_criteria_appointment_type(self) -> None:
5677
"""
57-
Adds join to appointment_t table based on appointment selection strategy.
58-
Requires prior join to latest episode (ep). Aliases the appointment table as 'ap'.
59-
60-
Accepts values:
61-
- "any_appointment_in_latest_episode"
62-
- "latest_appointment_in_latest_episode"
63-
- "earlier_appointment_in_latest_episode"
64-
- "later_appointment_in_latest_episode"
78+
Filters appointments by slot type (e.g. clinic, phone).
79+
Requires prior join to appointment_t as alias 'ap' (via WHICH_APPOINTMENT).
80+
81+
Uses comparator and resolves slot type label to ID via AppointmentSlotType.
6582
"""
6683
try:
67-
value = self.criteria_value.strip().lower()
68-
ap_alias = "ap"
69-
apr_alias = "ap_prev" # Simulated prior alias for test support
84+
comparator = self.criteria_comparator
85+
value = self.criteria_value.strip()
86+
slot_type_id = AppointmentSlotType.get_id(value)
7087

71-
self._add_join_to_latest_episode()
72-
self.sql_from.append(
73-
f"INNER JOIN appointment_t {ap_alias} ON {ap_alias}.subject_epis_id = ep.subject_epis_id"
88+
self.sql_where.append(
89+
f"AND ap.appointment_slot_type_id {comparator} {slot_type_id}"
7490
)
7591

76-
if value == "any_appointment_in_latest_episode":
77-
return
78-
elif value == "latest_appointment_in_latest_episode":
79-
self.sql_from.append(
80-
f"AND {ap_alias}.appointment_id = ("
81-
f" SELECT MAX(apx.appointment_id)"
82-
f" FROM appointment_t apx"
83-
f" WHERE apx.subject_epis_id = ep.subject_epis_id"
84-
f" AND apx.void = 'N')"
85-
)
86-
elif value == "earlier_appointment_in_latest_episode":
87-
self.sql_from.append(
88-
f"AND {ap_alias}.appointment_id < {apr_alias}.appointment_id"
89-
)
90-
elif value == "later_appointment_in_latest_episode":
91-
self.sql_from.append(
92-
f"AND {ap_alias}.appointment_id > {apr_alias}.appointment_id"
93-
)
94-
else:
95-
raise ValueError(f"Invalid appointment selection value: {value}")
96-
9792
except Exception:
9893
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)

utils/oracle/subject_selection_query_builder.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from classes.subject import Subject
2626
from classes.user import User
2727
from classes.selection_builder_exception import SelectionBuilderException
28+
from classes.appointments_slot_type import AppointmentSlotType
2829

2930

3031
class SubjectSelectionQueryBuilder:
@@ -1562,6 +1563,25 @@ def _add_join_to_appointments(self) -> None:
15621563
except Exception:
15631564
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
15641565

1566+
def _add_criteria_appointment_type(self) -> None:
1567+
"""
1568+
Filters appointments by slot type (e.g. clinic, phone).
1569+
Requires prior join to appointment_t as alias 'ap' (via WHICH_APPOINTMENT).
1570+
1571+
Uses comparator and resolves slot type label to ID via AppointmentSlotType.
1572+
"""
1573+
try:
1574+
comparator = self.criteria_comparator
1575+
value = self.criteria_value.strip()
1576+
slot_type_id = AppointmentSlotType.get_id(value)
1577+
1578+
self.sql_where.append(
1579+
f"AND ap.appointment_slot_type_id {comparator} {slot_type_id}"
1580+
)
1581+
1582+
except Exception:
1583+
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
1584+
15651585
# ------------------------------------------------------------------------
15661586
# 🧬 CADS Clinical Dataset Filters
15671587
# ------------------------------------------------------------------------

utils/oracle/test_subject_criteria_dev.py

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,16 @@
2929
# === Example usage ===
3030
# Replace the examples below with your tests for the method you want to test
3131

32-
# === Test: WHICH_APPOINTMENT — any_appointment_in_latest_episode ===
33-
builder = MockSelectionBuilder(
34-
SubjectSelectionCriteriaKey.WHICH_APPOINTMENT, "any_appointment_in_latest_episode"
35-
)
36-
builder._add_join_to_appointments()
37-
print("=== WHICH_APPOINTMENT — any_appointment_in_latest_episode ===")
32+
# === Test: APPOINTMENT_TYPE — phone ===
33+
builder = MockSelectionBuilder(SubjectSelectionCriteriaKey.APPOINTMENT_TYPE, "phone")
34+
builder.criteria_comparator = "="
35+
builder._add_criteria_appointment_type()
36+
print("=== APPOINTMENT_TYPE — phone ===")
3837
print(builder.dump_sql(), end="\n\n")
3938

40-
# === Test: WHICH_APPOINTMENT — latest_appointment_in_latest_episode ===
41-
builder = MockSelectionBuilder(
42-
SubjectSelectionCriteriaKey.WHICH_APPOINTMENT,
43-
"latest_appointment_in_latest_episode",
44-
)
45-
builder._add_join_to_appointments()
46-
print("=== WHICH_APPOINTMENT — latest_appointment_in_latest_episode ===")
47-
print(builder.dump_sql(), end="\n\n")
48-
49-
# === Test: WHICH_APPOINTMENT — earlier_appointment_in_latest_episode ===
50-
builder = MockSelectionBuilder(
51-
SubjectSelectionCriteriaKey.WHICH_APPOINTMENT,
52-
"earlier_appointment_in_latest_episode",
53-
)
54-
builder._add_join_to_appointments()
55-
print("=== WHICH_APPOINTMENT — earlier_appointment_in_latest_episode ===")
56-
print(builder.dump_sql(), end="\n\n")
57-
58-
# === Test: WHICH_APPOINTMENT — later_appointment_in_latest_episode ===
59-
builder = MockSelectionBuilder(
60-
SubjectSelectionCriteriaKey.WHICH_APPOINTMENT, "later_appointment_in_latest_episode"
61-
)
62-
builder._add_join_to_appointments()
63-
print("=== WHICH_APPOINTMENT — later_appointment_in_latest_episode ===")
39+
# === Test: APPOINTMENT_TYPE — clinic !== ===
40+
builder = MockSelectionBuilder(SubjectSelectionCriteriaKey.APPOINTMENT_TYPE, "clinic")
41+
builder.criteria_comparator = "!="
42+
builder._add_criteria_appointment_type()
43+
print("=== APPOINTMENT_TYPE — clinic !== ===")
6444
print(builder.dump_sql(), end="\n\n")

0 commit comments

Comments
 (0)