Skip to content

Commit 83e54a7

Browse files
Feature/bcss 21007 subject selection query builder fix (#108)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> Fixing some broken methods in the subject selection query builder util and adding new ones. ## Context <!-- Why is this change required? What problem does it solve? --> Allows the subject selection query builder to function as intended and cover all the use cases that the java version does. ## Type of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. --> - [x] Refactoring (non-breaking change) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would change existing functionality) - [ ] Bug fix (non-breaking change which fixes an issue) ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I am familiar with the [contributing guidelines](https://github.com/nhs-england-tools/playwright-python-blueprint/blob/main/CONTRIBUTING.md) - [x] I have followed the code style of the project - [ ] I have added tests to cover my changes (where appropriate) - [x] I have updated the documentation accordingly - [ ] This PR is a result of pair or mob programming --- ## Sensitive Information Declaration To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including [PII (Personal Identifiable Information) / PID (Personal Identifiable Data)](https://digital.nhs.uk/data-and-information/keeping-data-safe-and-benefitting-the-public) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter. - [x] I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.
1 parent ce60049 commit 83e54a7

29 files changed

+3796
-296
lines changed

classes/asa_grade_type.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from enum import Enum
2+
from typing import Optional, Dict
3+
4+
5+
class ASAGradeType(Enum):
6+
"""
7+
Enum representing ASA grades for colonoscopy assessment scenarios,
8+
with valid value IDs and descriptions.
9+
"""
10+
11+
IFIT = (17009, "I - Fit")
12+
II_RELEVANT_DISEASE = (17010, "II - Relevant disease")
13+
III_RESTRICTIVE_DISEASE = (17011, "III - Restrictive disease")
14+
IV_LIFE_THREATENING_DISEASE = (17012, "IV - Life threatening disease")
15+
V_MORIBUND = (17013, "V - Moribund")
16+
NOT_APPLICABLE = (17014, "Not Applicable")
17+
NOT_KNOWN = (17015, "Not Known")
18+
NULL = (None, "")
19+
20+
def __init__(self, valid_value_id: Optional[int], description: str):
21+
self._valid_value_id: Optional[int] = valid_value_id
22+
self._description: str = description
23+
24+
@property
25+
def valid_value_id(self) -> Optional[int]:
26+
"""Returns the valid value ID for the ASA grade."""
27+
return self._valid_value_id
28+
29+
@property
30+
def description(self) -> str:
31+
"""Returns the description for the ASA grade."""
32+
return self._description
33+
34+
@classmethod
35+
def _build_maps(cls) -> None:
36+
"""
37+
Initializes internal lookup maps for ASAGradeType enum members.
38+
39+
It ensures these maps are built only once per class, using `hasattr` to prevent
40+
redundant reinitialization.
41+
"""
42+
if not hasattr(cls, "_descriptions"):
43+
cls._descriptions: Dict[str, ASAGradeType] = {}
44+
cls._lowercase_descriptions: Dict[str, ASAGradeType] = {}
45+
cls._valid_value_ids: Dict[Optional[int], ASAGradeType] = {}
46+
for item in cls:
47+
cls._descriptions[item.description] = item
48+
cls._lowercase_descriptions[item.description.lower()] = item
49+
cls._valid_value_ids[item.valid_value_id] = item
50+
51+
@classmethod
52+
def by_description(cls, description: str) -> Optional["ASAGradeType"]:
53+
"""
54+
Returns the ASAGradeType matching the given description.
55+
"""
56+
cls._build_maps()
57+
return cls._descriptions.get(description)
58+
59+
@classmethod
60+
def by_description_case_insensitive(
61+
cls, description: str
62+
) -> Optional["ASAGradeType"]:
63+
"""
64+
Returns the ASAGradeType matching the given description (case-insensitive).
65+
"""
66+
cls._build_maps()
67+
return cls._lowercase_descriptions.get(description.lower())
68+
69+
@classmethod
70+
def by_valid_value_id(
71+
cls, valid_value_id: Optional[int]
72+
) -> Optional["ASAGradeType"]:
73+
"""
74+
Returns the ASAGradeType matching the given valid value ID.
75+
"""
76+
cls._build_maps()
77+
return cls._valid_value_ids.get(valid_value_id)
78+
79+
def get_valid_value_id(self) -> Optional[int]:
80+
"""
81+
Returns the valid value ID for the ASA grade.
82+
"""
83+
return self._valid_value_id
84+
85+
def get_description(self) -> str:
86+
"""
87+
Returns the description for the ASA grade.
88+
"""
89+
return self._description

classes/cancer_treatment_intent.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from enum import Enum
2+
from typing import Optional, Dict
3+
4+
5+
class CancerTreatmentIntent(Enum):
6+
"""
7+
Enum representing types of cancer treatment intent with associated valid value IDs and descriptions.
8+
Provides utility methods to retrieve enum instances by description or ID.
9+
"""
10+
11+
CURATIVE = (17370, "Curative")
12+
PALLIATIVE = (17371, "Palliative")
13+
UNCERTAIN = (17372, "Uncertain")
14+
NOT_KNOWN = (17373, "Not Known")
15+
16+
def __init__(self, valid_value_id: int, description: str):
17+
self._valid_value_id = valid_value_id
18+
self._description = description
19+
20+
@property
21+
def valid_value_id(self) -> int:
22+
"""Returns the valid value ID for the treatment given."""
23+
return self._valid_value_id
24+
25+
@property
26+
def description(self) -> str:
27+
"""Returns the description for the treatment given."""
28+
return self._description
29+
30+
@classmethod
31+
def _build_maps(cls) -> None:
32+
"""
33+
Initializes internal lookup maps for CanterTreatmentIntent enum members.
34+
35+
It ensures these maps are built only once per class, using `hasattr` to prevent
36+
redundant reinitialization.
37+
"""
38+
if not hasattr(cls, "_descriptions"):
39+
cls._descriptions: Dict[str, CancerTreatmentIntent] = {}
40+
cls._lowercase_descriptions: Dict[str, CancerTreatmentIntent] = {}
41+
cls._valid_value_ids: Dict[int, CancerTreatmentIntent] = {}
42+
for item in cls:
43+
cls._descriptions[item.description] = item
44+
cls._lowercase_descriptions[item.description.lower()] = item
45+
cls._valid_value_ids[item.valid_value_id] = item
46+
47+
@classmethod
48+
def by_description(cls, description: str) -> Optional["CancerTreatmentIntent"]:
49+
"""
50+
Returns the CancerTreatmentIntent matching the given description.
51+
"""
52+
cls._build_maps()
53+
return cls._descriptions.get(description)
54+
55+
@classmethod
56+
def by_description_case_insensitive(
57+
cls, description: str
58+
) -> Optional["CancerTreatmentIntent"]:
59+
"""
60+
Returns the CancerTreatmentIntent matching the given description (case-insensitive).
61+
"""
62+
cls._build_maps()
63+
return cls._lowercase_descriptions.get(description.lower())
64+
65+
@classmethod
66+
def by_valid_value_id(
67+
cls, valid_value_id: int
68+
) -> Optional["CancerTreatmentIntent"]:
69+
"""
70+
Returns the CancerTreatmentIntent matching the given valid value ID.
71+
"""
72+
cls._build_maps()
73+
return cls._valid_value_ids.get(valid_value_id)
74+
75+
def get_id(self) -> int:
76+
"""Returns the valid value ID for the CancerTreatmentIntent given."""
77+
return self._valid_value_id
78+
79+
def get_description(self) -> str:
80+
"""Returns the description for the CancerTreatmentIntent given."""
81+
return self._description
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from enum import Enum
2+
from typing import Optional, Dict
3+
4+
5+
class DiagnosisDateReasonType(Enum):
6+
"""
7+
Enum representing diagnosis date reasons with valid value IDs and descriptions.
8+
"""
9+
10+
TWO_DNAS_OF_COLONOSCOPY_ASSESSMENT_APPT = (
11+
305521,
12+
"2 DNAs of colonoscopy assessment appt",
13+
)
14+
INCORRECT_INFORMATION_PREVIOUSLY_ENTERED = (
15+
305501,
16+
"Incorrect information previously entered",
17+
)
18+
OTHER = (305500, "Other")
19+
PATIENT_CHOICE = (305522, "Patient choice")
20+
PATIENT_COULD_NOT_BE_CONTACTED = (305505, "Patient could not be contacted")
21+
PATIENT_DECEASED = (305503, "Patient deceased")
22+
PATIENT_DECLINED_ALL_APPOINTMENTS = (305520, "Patient declined all appointments")
23+
PATIENT_EMIGRATED = (305504, "Patient emigrated")
24+
REOPENED_OLD_EPISODE_DATE_UNKNOWN = (305502, "Reopened old episode, date unknown")
25+
SSPI_UPDATE_PATIENT_DECEASED = (305525, "SSPI update - patient deceased")
26+
SSPI_UPDATE_PATIENT_EMIGRATED = (305524, "SSPI update - patient emigrated")
27+
SYSTEM_CLOSURE_AFTER_NO_INPUT_OF_DIAGNOSIS_DATE = (
28+
305519,
29+
"System closure after no input of diagnosis date",
30+
)
31+
NULL = (None, "NULL")
32+
NOT_NULL = (None, "NOT NULL")
33+
34+
def __init__(self, valid_value_id: Optional[int], description: str):
35+
self._valid_value_id: Optional[int] = valid_value_id
36+
self._description: str = description
37+
38+
@property
39+
def valid_value_id(self) -> Optional[int]:
40+
"""Returns the valid value ID for the diagnosis date reason."""
41+
return self._valid_value_id
42+
43+
@property
44+
def description(self) -> str:
45+
"""Returns the description for the diagnosis date reason."""
46+
return self._description
47+
48+
@classmethod
49+
def _build_maps(cls) -> None:
50+
"""
51+
Initializes internal lookup maps for DiagnosisDateReasonType enum members.
52+
53+
It ensures these maps are built only once per class, using `hasattr` to prevent
54+
redundant reinitialization.
55+
"""
56+
if not hasattr(cls, "_descriptions"):
57+
cls._descriptions: Dict[str, DiagnosisDateReasonType] = {}
58+
cls._lowercase_descriptions: Dict[str, DiagnosisDateReasonType] = {}
59+
cls._valid_value_ids: Dict[Optional[int], DiagnosisDateReasonType] = {}
60+
for item in cls:
61+
cls._descriptions[item.description] = item
62+
cls._lowercase_descriptions[item.description.lower()] = item
63+
cls._valid_value_ids[item.valid_value_id] = item
64+
65+
@classmethod
66+
def by_description(cls, description: str) -> Optional["DiagnosisDateReasonType"]:
67+
"""
68+
Returns the DiagnosisDateReasonType matching the given description.
69+
"""
70+
cls._build_maps()
71+
return cls._descriptions.get(description)
72+
73+
@classmethod
74+
def by_description_case_insensitive(
75+
cls, description: str
76+
) -> Optional["DiagnosisDateReasonType"]:
77+
"""
78+
Returns the DiagnosisDateReasonType matching the given description (case-insensitive).
79+
"""
80+
cls._build_maps()
81+
return cls._lowercase_descriptions.get(description.lower())
82+
83+
@classmethod
84+
def by_valid_value_id(
85+
cls, valid_value_id: Optional[int]
86+
) -> Optional["DiagnosisDateReasonType"]:
87+
"""
88+
Returns the DiagnosisDateReasonType matching the given valid value ID.
89+
"""
90+
cls._build_maps()
91+
return cls._valid_value_ids.get(valid_value_id)
92+
93+
def get_valid_value_id(self) -> Optional[int]:
94+
"""
95+
Returns the valid value ID for the diagnosis date reason.
96+
"""
97+
return self._valid_value_id
98+
99+
def get_description(self) -> str:
100+
"""
101+
Returns the description for the diagnosis date reason.
102+
"""
103+
return self._description
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from enum import Enum
2+
from typing import Optional, Dict
3+
4+
5+
class DiagnosticTestReferralType(Enum):
6+
"""
7+
Enum representing diagnostic test referral types with valid value IDs and descriptions.
8+
"""
9+
10+
ENDOSCOPIC = (20356, "Endoscopic")
11+
RADIOLOGICAL = (20357, "Radiological")
12+
13+
def __init__(self, valid_value_id: int, description: str):
14+
self._valid_value_id: int = valid_value_id
15+
self._description: str = description
16+
17+
@property
18+
def valid_value_id(self) -> int:
19+
"""Returns the valid value ID for the diagnostic test referral type."""
20+
return self._valid_value_id
21+
22+
@property
23+
def description(self) -> str:
24+
"""Returns the description for the diagnostic test referral type."""
25+
return self._description
26+
27+
@classmethod
28+
def _build_maps(cls) -> None:
29+
"""
30+
Initializes internal lookup maps for DiagnosticTestReferralType enum members.
31+
32+
It ensures these maps are built only once per class, using `hasattr` to prevent
33+
redundant reinitialization.
34+
"""
35+
if not hasattr(cls, "_descriptions"):
36+
cls._descriptions: Dict[str, DiagnosticTestReferralType] = {}
37+
cls._lowercase_descriptions: Dict[str, DiagnosticTestReferralType] = {}
38+
cls._valid_value_ids: Dict[int, DiagnosticTestReferralType] = {}
39+
for item in cls:
40+
cls._descriptions[item.description] = item
41+
cls._lowercase_descriptions[item.description.lower()] = item
42+
cls._valid_value_ids[item.valid_value_id] = item
43+
44+
@classmethod
45+
def by_description(cls, description: str) -> Optional["DiagnosticTestReferralType"]:
46+
"""
47+
Returns the DiagnosticTestReferralType matching the given description.
48+
"""
49+
cls._build_maps()
50+
return cls._descriptions.get(description)
51+
52+
@classmethod
53+
def by_description_case_insensitive(
54+
cls, description: str
55+
) -> Optional["DiagnosticTestReferralType"]:
56+
"""
57+
Returns the DiagnosticTestReferralType matching the given description (case-insensitive).
58+
"""
59+
cls._build_maps()
60+
return cls._lowercase_descriptions.get(description.lower())
61+
62+
@classmethod
63+
def by_valid_value_id(
64+
cls, valid_value_id: int
65+
) -> Optional["DiagnosticTestReferralType"]:
66+
"""
67+
Returns the DiagnosticTestReferralType matching the given valid value ID.
68+
"""
69+
cls._build_maps()
70+
return cls._valid_value_ids.get(valid_value_id)
71+
72+
def get_id(self) -> int:
73+
"""
74+
Returns the valid value ID for the diagnostic test referral type.
75+
"""
76+
return self._valid_value_id
77+
78+
def get_description(self) -> str:
79+
"""
80+
Returns the description for the diagnostic test referral type.
81+
"""
82+
return self._description

0 commit comments

Comments
 (0)