canvas 0.3.1__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of canvas might be problematic. Click here for more details.
- {canvas-0.3.1.dist-info → canvas-0.5.0.dist-info}/METADATA +4 -2
- {canvas-0.3.1.dist-info → canvas-0.5.0.dist-info}/RECORD +76 -37
- canvas_cli/apps/emit/emit.py +1 -1
- canvas_cli/apps/logs/logs.py +6 -6
- canvas_cli/apps/plugin/plugin.py +11 -7
- canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/protocols/my_protocol.py +3 -7
- canvas_cli/tests.py +12 -5
- canvas_cli/utils/context/context.py +2 -2
- canvas_cli/utils/context/tests.py +5 -4
- canvas_cli/utils/print/print.py +1 -1
- canvas_cli/utils/print/tests.py +2 -3
- canvas_generated/messages/events_pb2.py +2 -2
- canvas_generated/messages/events_pb2.pyi +112 -0
- canvas_sdk/base.py +2 -1
- canvas_sdk/commands/base.py +25 -25
- canvas_sdk/commands/tests/protocol/tests.py +5 -3
- canvas_sdk/commands/tests/test_utils.py +8 -44
- canvas_sdk/commands/tests/unit/tests.py +3 -3
- canvas_sdk/data/client.py +1 -1
- canvas_sdk/effects/banner_alert/tests.py +12 -4
- canvas_sdk/effects/patient_chart_summary_configuration.py +1 -0
- canvas_sdk/effects/protocol_card/protocol_card.py +1 -1
- canvas_sdk/effects/protocol_card/tests.py +2 -2
- canvas_sdk/protocols/clinical_quality_measure.py +1 -0
- canvas_sdk/utils/http.py +2 -2
- canvas_sdk/v1/data/common.py +46 -0
- canvas_sdk/v1/data/detected_issue.py +52 -0
- canvas_sdk/v1/data/imaging.py +102 -0
- canvas_sdk/v1/data/lab.py +182 -10
- canvas_sdk/v1/data/patient.py +4 -1
- canvas_sdk/v1/data/protocol_override.py +58 -0
- canvas_sdk/v1/data/questionnaire.py +4 -2
- canvas_sdk/value_set/__init__.py +0 -0
- canvas_sdk/value_set/tests/test_value_sets.py +9 -6
- canvas_sdk/value_set/v2022/__init__.py +0 -0
- canvas_sdk/value_set/v2022/intervention.py +0 -24
- canvas_sdk/value_set/value_set.py +24 -21
- plugin_runner/authentication.py +3 -7
- plugin_runner/plugin_runner.py +106 -33
- plugin_runner/sandbox.py +23 -9
- plugin_runner/tests/__init__.py +0 -0
- plugin_runner/tests/data/plugins/.gitkeep +0 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/CANVAS_MANIFEST.json +29 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/README.md +12 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/example_plugin/protocols/my_protocol.py +18 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/CANVAS_MANIFEST.json +29 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/README.md +12 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/other_module/base.py +3 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v1/protocols/my_protocol.py +18 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/CANVAS_MANIFEST.json +29 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/README.md +12 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/other_module/base.py +6 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v2/protocols/my_protocol.py +18 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/CANVAS_MANIFEST.json +29 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/README.md +12 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/other_module/base.py +8 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_outside_plugin_v3/protocols/my_protocol.py +18 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/CANVAS_MANIFEST.json +29 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/README.md +12 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/other_module/base.py +3 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/__init__.py +0 -0
- plugin_runner/tests/fixtures/plugins/test_module_imports_plugin/protocols/my_protocol.py +18 -0
- plugin_runner/tests/test_plugin_runner.py +208 -0
- plugin_runner/tests/test_sandbox.py +113 -0
- settings.py +23 -0
- {canvas-0.3.1.dist-info → canvas-0.5.0.dist-info}/WHEEL +0 -0
- {canvas-0.3.1.dist-info → canvas-0.5.0.dist-info}/entry_points.txt +0 -0
|
@@ -107,7 +107,7 @@ def test_apply_method_raises_error_without_patient_id_and_key() -> None:
|
|
|
107
107
|
],
|
|
108
108
|
)
|
|
109
109
|
def test_add_recommendations(
|
|
110
|
-
init_params: dict[
|
|
110
|
+
init_params: dict[Any, Any], rec1_params: dict[Any, Any], rec2_params: dict[Any, Any]
|
|
111
111
|
) -> None:
|
|
112
112
|
p = ProtocolCard(**init_params)
|
|
113
113
|
p.add_recommendation(**rec1_params)
|
|
@@ -156,7 +156,7 @@ def test_add_recommendations(
|
|
|
156
156
|
],
|
|
157
157
|
)
|
|
158
158
|
def test_add_recommendations_from_commands(
|
|
159
|
-
Command: _BaseCommand, init_params: dict[str, str]
|
|
159
|
+
Command: type[_BaseCommand], init_params: dict[str, str]
|
|
160
160
|
) -> None:
|
|
161
161
|
cmd = Command(**init_params)
|
|
162
162
|
p = ProtocolCard(patient_id="uuid", key="commands")
|
canvas_sdk/utils/http.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import time
|
|
2
2
|
from functools import wraps
|
|
3
|
-
from typing import Any, Callable, Mapping, TypeVar
|
|
3
|
+
from typing import Any, Callable, Mapping, TypeVar, cast
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
6
|
import statsd
|
|
@@ -28,7 +28,7 @@ class Http:
|
|
|
28
28
|
self.statsd_client.timing(f"http_{fn.__name__}", timing)
|
|
29
29
|
return result
|
|
30
30
|
|
|
31
|
-
return wrapper
|
|
31
|
+
return cast(F, wrapper)
|
|
32
32
|
|
|
33
33
|
@measure_time
|
|
34
34
|
def get(
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DocumentReviewMode(models.TextChoices):
|
|
5
|
+
"""Choices for document reviews."""
|
|
6
|
+
|
|
7
|
+
REVIEW_REQUIRED = "RR", "Review required"
|
|
8
|
+
ALREADY_REVIEWED_OFFLINE = "AR", "Already reviewed offline"
|
|
9
|
+
REVIEW_NOT_REQUIRED = "RN", "Review not required"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OrderStatus(models.TextChoices):
|
|
13
|
+
"""Choices for Order statuses."""
|
|
14
|
+
|
|
15
|
+
PROPOSED = "proposed", "Proposed"
|
|
16
|
+
DRAFT = "draft", "Draft"
|
|
17
|
+
PLANNED = "planned", "Planned"
|
|
18
|
+
REQUESTED = "requested", "Requested"
|
|
19
|
+
RECEIVED = "received", "Received"
|
|
20
|
+
ACCEPTED = "accepted", "Accepted"
|
|
21
|
+
IN_PROGRESS = "in-progress", "In-progress"
|
|
22
|
+
REVIEW = "review", "Review"
|
|
23
|
+
COMPLETED = "completed", "Completed"
|
|
24
|
+
CANCELLED = "cancelled", "Cancelled"
|
|
25
|
+
SUSPENDED = "suspended", "Suspended"
|
|
26
|
+
REJECTED = "rejected", "Rejected"
|
|
27
|
+
FAILED = "failed", "Failed"
|
|
28
|
+
ENTERED_IN_ERROR = "EIE", "Entered in Error"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ReviewPatientCommunicationMethod(models.TextChoices):
|
|
32
|
+
"""Choices for patient communication regarding reviews."""
|
|
33
|
+
|
|
34
|
+
DELEGATED_CALL_CAN_LEAVE_MESSAGE = "DM", "delegate call, can leave message"
|
|
35
|
+
DELEGATED_CALL_NEED_ANSWER = "DA", "delegate call, need patient to answer"
|
|
36
|
+
DELEGATED_LETTER = "DL", "delegate letter"
|
|
37
|
+
DO_NOT_COMMUNICATE = "DC", "do not communicate"
|
|
38
|
+
ALREADY_LEFT_MESSAGE = "AM", "already left message"
|
|
39
|
+
ALREADY_REVIEWED_WITH_PATIENT = "AR", "already reviewed with patient"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ReviewStatus(models.TextChoices):
|
|
43
|
+
"""Status choices for reviews."""
|
|
44
|
+
|
|
45
|
+
STATUS_REVIEWING = "reviewing", "reviewing"
|
|
46
|
+
STATUS_REVIEWED = "reviewed", "reviewed"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from canvas_sdk.v1.data import Patient
|
|
4
|
+
from canvas_sdk.v1.data.user import CanvasUser
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DetectedIssue(models.Model):
|
|
8
|
+
"""DetectedIssue."""
|
|
9
|
+
|
|
10
|
+
class Meta:
|
|
11
|
+
managed = False
|
|
12
|
+
app_label = "canvas_sdk"
|
|
13
|
+
db_table = "canvas_sdk_data_api_detectedissue_001"
|
|
14
|
+
|
|
15
|
+
id = models.UUIDField()
|
|
16
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
17
|
+
created = models.DateTimeField()
|
|
18
|
+
modified = models.DateTimeField()
|
|
19
|
+
identified = models.DateTimeField()
|
|
20
|
+
deleted = models.BooleanField()
|
|
21
|
+
originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
22
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
23
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
24
|
+
patient = models.ForeignKey(
|
|
25
|
+
Patient, on_delete=models.DO_NOTHING, related_name="detected_issues"
|
|
26
|
+
)
|
|
27
|
+
code = models.CharField()
|
|
28
|
+
status = models.CharField()
|
|
29
|
+
severity = models.CharField()
|
|
30
|
+
reference = models.CharField()
|
|
31
|
+
issue_identifier = models.CharField()
|
|
32
|
+
issue_identifier_system = models.CharField()
|
|
33
|
+
detail = models.TextField()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DetectedIssueEvidence(models.Model):
|
|
37
|
+
"""DetectedIssueEvidence."""
|
|
38
|
+
|
|
39
|
+
class Meta:
|
|
40
|
+
managed = False
|
|
41
|
+
app_label = "canvas_sdk"
|
|
42
|
+
db_table = "canvas_sdk_data_api_detectedissueevidence_001"
|
|
43
|
+
|
|
44
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
45
|
+
system = models.CharField()
|
|
46
|
+
version = models.CharField()
|
|
47
|
+
code = models.CharField()
|
|
48
|
+
display = models.CharField()
|
|
49
|
+
user_selected = models.BooleanField()
|
|
50
|
+
detected_issue = models.ForeignKey(
|
|
51
|
+
DetectedIssue, on_delete=models.DO_NOTHING, related_name="evidence"
|
|
52
|
+
)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from canvas_sdk.v1.data.common import (
|
|
4
|
+
DocumentReviewMode,
|
|
5
|
+
OrderStatus,
|
|
6
|
+
ReviewPatientCommunicationMethod,
|
|
7
|
+
ReviewStatus,
|
|
8
|
+
)
|
|
9
|
+
from canvas_sdk.v1.data.patient import Patient
|
|
10
|
+
from canvas_sdk.v1.data.user import CanvasUser
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ImagingOrder(models.Model):
|
|
14
|
+
"""Model to read ImagingOrder data."""
|
|
15
|
+
|
|
16
|
+
class Meta:
|
|
17
|
+
managed = False
|
|
18
|
+
app_label = "canvas_sdk"
|
|
19
|
+
db_table = "canvas_sdk_data_api_imagingorder_001"
|
|
20
|
+
|
|
21
|
+
id = models.UUIDField()
|
|
22
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
23
|
+
created = models.DateTimeField()
|
|
24
|
+
modified = models.DateTimeField()
|
|
25
|
+
originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
26
|
+
deleted = models.BooleanField()
|
|
27
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
28
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
29
|
+
patient = models.ForeignKey(Patient, on_delete=models.DO_NOTHING, related_name="imaging_orders")
|
|
30
|
+
# TODO - uncomment when Note model is complete
|
|
31
|
+
# note = models.ForeigneKey(Note, on_delete=models.DO_NOTHING, related_name="imaging_orders")
|
|
32
|
+
imaging = models.CharField()
|
|
33
|
+
# TODO - uncomment when ServiceProvider model is complete
|
|
34
|
+
# imaging_center = models.ForeignKey(ServiceProvider, related_name="imaging_orders", null=True, on_delete=models.DO_NOTHING)
|
|
35
|
+
note_to_radiologist = models.CharField()
|
|
36
|
+
internal_comment = models.CharField()
|
|
37
|
+
status = models.CharField(choices=OrderStatus)
|
|
38
|
+
date_time_ordered = models.DateTimeField()
|
|
39
|
+
priority = models.CharField()
|
|
40
|
+
# TODO - uncomment when Staff model is complete
|
|
41
|
+
# ordering_provider = models.ForeignKey(Staff, on_delete=models.CASCADE, related_name="imaging_orders", null=True)
|
|
42
|
+
delegated = models.BooleanField(default=False)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ImagingReview(models.Model):
|
|
46
|
+
"""Model to read ImagingReview data."""
|
|
47
|
+
|
|
48
|
+
class Meta:
|
|
49
|
+
managed = False
|
|
50
|
+
app_label = "canvas_sdk"
|
|
51
|
+
db_table = "canvas_sdk_data_api_imagingreview_001"
|
|
52
|
+
|
|
53
|
+
id = models.UUIDField()
|
|
54
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
55
|
+
created = models.DateTimeField()
|
|
56
|
+
modified = models.DateTimeField()
|
|
57
|
+
originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
58
|
+
deleted = models.BooleanField()
|
|
59
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
60
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
61
|
+
patient_communication_method = models.CharField(choices=ReviewPatientCommunicationMethod)
|
|
62
|
+
# TODO - uncomment when Note model is complete
|
|
63
|
+
# note = models.ForeignKey(Note, on_delete=models.DO_NOTHING, related_name="imaging_reviews")
|
|
64
|
+
internal_comment = models.CharField()
|
|
65
|
+
message_to_patient = models.CharField()
|
|
66
|
+
is_released_to_patient = models.BooleanField()
|
|
67
|
+
status = models.CharField(choices=ReviewStatus)
|
|
68
|
+
patient = models.ForeignKey(
|
|
69
|
+
Patient, on_delete=models.DO_NOTHING, related_name="imaging_reviews"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ImagingReport(models.Model):
|
|
74
|
+
"""Model to read ImagingReport data."""
|
|
75
|
+
|
|
76
|
+
class ImagingReportSource(models.TextChoices):
|
|
77
|
+
RADIOLOGY_FROM_PATIENT = "RADIOLOGY_PATIENT", "Radiology Report From Patient"
|
|
78
|
+
VERBAL_FROM_PATIENT = "VERBAL_PATIENT", "Verbal Report From Patient"
|
|
79
|
+
DIRECTLY_REPORT = "DIRECTLY_RADIOLOGY", "Directly Radiology Report"
|
|
80
|
+
|
|
81
|
+
class Meta:
|
|
82
|
+
managed = False
|
|
83
|
+
app_label = "canvas_sdk"
|
|
84
|
+
db_table = "canvas_sdk_data_api_imagingreport_001"
|
|
85
|
+
|
|
86
|
+
id = models.UUIDField()
|
|
87
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
88
|
+
created = models.DateTimeField()
|
|
89
|
+
modified = models.DateTimeField()
|
|
90
|
+
review_mode = models.CharField(choices=DocumentReviewMode)
|
|
91
|
+
junked = models.BooleanField()
|
|
92
|
+
requires_signature = models.BooleanField()
|
|
93
|
+
assigned_date = models.DateTimeField()
|
|
94
|
+
patient = models.ForeignKey(
|
|
95
|
+
Patient, on_delete=models.DO_NOTHING, related_name="imaging_results"
|
|
96
|
+
)
|
|
97
|
+
order = models.ForeignKey(ImagingOrder, on_delete=models.DO_NOTHING, null=True)
|
|
98
|
+
source = models.CharField(choices=ImagingReportSource)
|
|
99
|
+
name = models.CharField()
|
|
100
|
+
result_date = models.DateField()
|
|
101
|
+
original_date = models.DateField()
|
|
102
|
+
review = models.ForeignKey(ImagingReview, null=True, on_delete=models.DO_NOTHING)
|
canvas_sdk/v1/data/lab.py
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
from django.db import models
|
|
2
2
|
|
|
3
3
|
from canvas_sdk.v1.data.base import CommittableModelManager
|
|
4
|
+
from canvas_sdk.v1.data.condition import Condition
|
|
4
5
|
from canvas_sdk.v1.data.patient import Patient
|
|
6
|
+
|
|
7
|
+
# from canvas_sdk.v1.data.staff import Staff
|
|
5
8
|
from canvas_sdk.v1.data.user import CanvasUser
|
|
6
9
|
|
|
7
10
|
|
|
11
|
+
class TransmissionType(models.TextChoices):
|
|
12
|
+
"""Choices for transmission types."""
|
|
13
|
+
|
|
14
|
+
FAX = "F", "fax"
|
|
15
|
+
HL7 = "H", "hl7"
|
|
16
|
+
MANUAL = "M", "manual"
|
|
17
|
+
|
|
18
|
+
|
|
8
19
|
class LabReport(models.Model):
|
|
9
20
|
"""A class representing a lab report."""
|
|
10
21
|
|
|
@@ -23,19 +34,23 @@ class LabReport(models.Model):
|
|
|
23
34
|
junked = models.BooleanField()
|
|
24
35
|
requires_signature = models.BooleanField()
|
|
25
36
|
assigned_date = models.DateTimeField()
|
|
26
|
-
patient = models.ForeignKey(
|
|
27
|
-
|
|
37
|
+
patient = models.ForeignKey(
|
|
38
|
+
Patient, on_delete=models.DO_NOTHING, related_name="lab_reports", null=True
|
|
39
|
+
)
|
|
40
|
+
transmission_type = models.CharField(choices=TransmissionType)
|
|
28
41
|
for_test_only = models.BooleanField()
|
|
29
42
|
external_id = models.CharField()
|
|
30
43
|
version = models.IntegerField()
|
|
31
44
|
requisition_number = models.CharField()
|
|
32
|
-
review = models.ForeignKey(
|
|
45
|
+
review = models.ForeignKey(
|
|
46
|
+
"LabReview", related_name="reports", on_delete=models.DO_NOTHING, null=True
|
|
47
|
+
)
|
|
33
48
|
original_date = models.DateTimeField()
|
|
34
49
|
date_performed = models.DateTimeField()
|
|
35
50
|
custom_document_name = models.CharField()
|
|
36
51
|
originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
37
|
-
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
38
|
-
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
52
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING, null=True)
|
|
53
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING, null=True)
|
|
39
54
|
deleted = models.BooleanField()
|
|
40
55
|
|
|
41
56
|
|
|
@@ -55,12 +70,12 @@ class LabReview(models.Model):
|
|
|
55
70
|
modified = models.DateTimeField()
|
|
56
71
|
originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
57
72
|
deleted = models.BooleanField()
|
|
58
|
-
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
59
|
-
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
73
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING, null=True)
|
|
74
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING, null=True)
|
|
60
75
|
internal_comment = models.TextField()
|
|
61
76
|
message_to_patient = models.CharField()
|
|
62
77
|
status = models.CharField()
|
|
63
|
-
patient = models.ForeignKey(Patient, on_delete=models.DO_NOTHING)
|
|
78
|
+
patient = models.ForeignKey(Patient, on_delete=models.DO_NOTHING, related_name="lab_reviews")
|
|
64
79
|
patient_communication_method = models.CharField()
|
|
65
80
|
|
|
66
81
|
|
|
@@ -76,7 +91,9 @@ class LabValue(models.Model):
|
|
|
76
91
|
dbid = models.BigIntegerField(primary_key=True)
|
|
77
92
|
created = models.DateTimeField()
|
|
78
93
|
modified = models.DateTimeField()
|
|
79
|
-
report = models.ForeignKey(
|
|
94
|
+
report = models.ForeignKey(
|
|
95
|
+
"LabReport", related_name="values", on_delete=models.DO_NOTHING, null=True
|
|
96
|
+
)
|
|
80
97
|
value = models.TextField()
|
|
81
98
|
units = models.CharField()
|
|
82
99
|
abnormal_flag = models.CharField()
|
|
@@ -98,7 +115,162 @@ class LabValueCoding(models.Model):
|
|
|
98
115
|
dbid = models.BigIntegerField(primary_key=True)
|
|
99
116
|
created = models.DateTimeField()
|
|
100
117
|
modified = models.DateTimeField()
|
|
101
|
-
value = models.ForeignKey(
|
|
118
|
+
value = models.ForeignKey(
|
|
119
|
+
LabValue, on_delete=models.DO_NOTHING, related_name="codings", null=True
|
|
120
|
+
)
|
|
102
121
|
code = models.CharField()
|
|
103
122
|
name = models.CharField()
|
|
104
123
|
system = models.CharField()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class LabOrder(models.Model):
|
|
127
|
+
"""A class representing a lab order."""
|
|
128
|
+
|
|
129
|
+
class SpecimenCollectionType(models.TextChoices):
|
|
130
|
+
"""Choices for specimen collection types."""
|
|
131
|
+
|
|
132
|
+
ON_LOCATION = "L", "on location"
|
|
133
|
+
PATIENT_SERVICE_CENTER = "P", "patient service center"
|
|
134
|
+
OTHER = "O", "other"
|
|
135
|
+
|
|
136
|
+
class CourtesyCopyType(models.TextChoices):
|
|
137
|
+
"""Choices for courtesy copy types."""
|
|
138
|
+
|
|
139
|
+
ACCOUNT = "A", "account"
|
|
140
|
+
FAX = "F", "fax"
|
|
141
|
+
PATIENT = "P", "patient"
|
|
142
|
+
|
|
143
|
+
class ManualProcessingStatus(models.TextChoices):
|
|
144
|
+
"""Choices for manual processing statuses."""
|
|
145
|
+
|
|
146
|
+
MANUAL_PROCESSING_STATUS_NEEDS_REVIEW = "NEEDS_REVIEW", "Needs Review"
|
|
147
|
+
MANUAL_PROCESSING_STATUS_IN_PROGRESS = "IN_PROGRESS", "In Progress"
|
|
148
|
+
MANUAL_PROCESSING_STATUS_PROCESSED = "PROCESSED", "Processed"
|
|
149
|
+
MANUAL_PROCESSING_STATUS_FLAGGED = "FLAGGED", "Flagged"
|
|
150
|
+
|
|
151
|
+
class Meta:
|
|
152
|
+
managed = False
|
|
153
|
+
app_label = "canvas_sdk"
|
|
154
|
+
db_table = "canvas_sdk_data_api_laborder_001"
|
|
155
|
+
|
|
156
|
+
id = models.UUIDField()
|
|
157
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
158
|
+
created = models.DateTimeField()
|
|
159
|
+
modified = models.DateTimeField()
|
|
160
|
+
originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
161
|
+
deleted = models.BooleanField()
|
|
162
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING, null=True)
|
|
163
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING, null=True)
|
|
164
|
+
patient = models.ForeignKey(Patient, on_delete=models.DO_NOTHING, related_name="lab_orders")
|
|
165
|
+
ontology_lab_partner = models.CharField()
|
|
166
|
+
# TODO - uncomment when the Note model is finished
|
|
167
|
+
# note = models.ForeignKey("Note", on_delete=models.DO_NOTHING)
|
|
168
|
+
comment = models.CharField()
|
|
169
|
+
requisition_number = models.CharField()
|
|
170
|
+
is_patient_bill = models.BooleanField(null=True)
|
|
171
|
+
date_ordered = models.DateTimeField()
|
|
172
|
+
fasting_status = models.BooleanField(null=True)
|
|
173
|
+
specimen_collection_type = models.CharField(choices=SpecimenCollectionType, null=True)
|
|
174
|
+
transmission_type = models.CharField(choices=TransmissionType, null=True)
|
|
175
|
+
courtesy_copy_type = models.CharField(choices=CourtesyCopyType, null=True)
|
|
176
|
+
courtesy_copy_number = models.CharField()
|
|
177
|
+
courtesy_copy_text = models.CharField()
|
|
178
|
+
# TODO - uncomment when Staff model is added
|
|
179
|
+
# ordering_provider = models.ForeignKey(Staff, on_delete=models.DO_NOTHING, null=True)
|
|
180
|
+
parent_order = models.ForeignKey("LabOrder", on_delete=models.DO_NOTHING, null=True)
|
|
181
|
+
healthgorilla_id = models.CharField()
|
|
182
|
+
manual_processing_status = models.CharField(choices=ManualProcessingStatus)
|
|
183
|
+
manual_processing_comment = models.CharField()
|
|
184
|
+
labcorp_abn_url = models.URLField()
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class LabOrderReason(models.Model):
|
|
188
|
+
"""A class representing a lab order reason."""
|
|
189
|
+
|
|
190
|
+
class LabReasonMode(models.TextChoices):
|
|
191
|
+
"""Choices for lab order reasons."""
|
|
192
|
+
|
|
193
|
+
MONITOR = "MO", "monitor"
|
|
194
|
+
INVESTIGATE = "IN", "investigate"
|
|
195
|
+
SCREEN_FOR = "SF", "screen for"
|
|
196
|
+
UNKNOWN = "UNK", "unknown"
|
|
197
|
+
|
|
198
|
+
class Meta:
|
|
199
|
+
managed = False
|
|
200
|
+
app_label = "canvas_sdk"
|
|
201
|
+
db_table = "canvas_sdk_data_api_laborderreason_001"
|
|
202
|
+
|
|
203
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
204
|
+
created = models.DateTimeField()
|
|
205
|
+
modified = models.DateTimeField()
|
|
206
|
+
originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
207
|
+
deleted = models.BooleanField()
|
|
208
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
209
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
210
|
+
order = models.ForeignKey(LabOrder, on_delete=models.DO_NOTHING, related_name="reasons")
|
|
211
|
+
mode = models.CharField(max_length=30, choices=LabReasonMode)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class LabOrderReasonCondition(models.Model):
|
|
215
|
+
"""A class representing a lab order reason's condition."""
|
|
216
|
+
|
|
217
|
+
class Meta:
|
|
218
|
+
managed = False
|
|
219
|
+
app_label = "canvas_sdk"
|
|
220
|
+
db_table = "canvas_sdk_data_api_laborderreasoncondition_001"
|
|
221
|
+
|
|
222
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
223
|
+
created = models.DateTimeField()
|
|
224
|
+
modified = models.DateTimeField()
|
|
225
|
+
reason = models.ForeignKey(
|
|
226
|
+
LabOrderReason, on_delete=models.DO_NOTHING, related_name="reason_conditions", null=True
|
|
227
|
+
)
|
|
228
|
+
condition = models.ForeignKey(
|
|
229
|
+
Condition,
|
|
230
|
+
on_delete=models.DO_NOTHING,
|
|
231
|
+
related_name="lab_order_reason_conditions",
|
|
232
|
+
null=True,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class LabTest(models.Model):
|
|
237
|
+
"""A class representing a lab test."""
|
|
238
|
+
|
|
239
|
+
class LabTestOrderStatus(models.TextChoices):
|
|
240
|
+
"""Choicees for lab test order statuses."""
|
|
241
|
+
|
|
242
|
+
NEW = "NE", "new"
|
|
243
|
+
STAGED_FOR_REQUISITION = "SR", "staged for requisition"
|
|
244
|
+
SENDING = "SE", "sending"
|
|
245
|
+
SENDING_FAILED = "SF", "sending failed"
|
|
246
|
+
PROCESSING = "PR", "processing"
|
|
247
|
+
PROCESSING_FAILED = "PF", "processing failed"
|
|
248
|
+
RECEIVED = "RE", "received"
|
|
249
|
+
REVIEWED = "RV", "reviewed"
|
|
250
|
+
INACTIVE = "IN", "inactive"
|
|
251
|
+
|
|
252
|
+
class Meta:
|
|
253
|
+
managed = False
|
|
254
|
+
app_label = "canvas_sdk"
|
|
255
|
+
db_table = "canvas_sdk_data_api_labtest_001"
|
|
256
|
+
|
|
257
|
+
id = models.UUIDField()
|
|
258
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
259
|
+
ontology_test_name = models.CharField(max_length=512, blank=True, default="")
|
|
260
|
+
ontology_test_code = models.CharField(max_length=512, blank=True, default="")
|
|
261
|
+
status = models.CharField(max_length=30, choices=LabTestOrderStatus)
|
|
262
|
+
report = models.ForeignKey(
|
|
263
|
+
LabReport, on_delete=models.DO_NOTHING, null=True, related_name="tests"
|
|
264
|
+
)
|
|
265
|
+
aoe_code = models.CharField(max_length=10, default="")
|
|
266
|
+
procedure_class = models.CharField(max_length=10, default="")
|
|
267
|
+
specimen_type = models.CharField()
|
|
268
|
+
specimen_source_code = models.CharField()
|
|
269
|
+
specimen_source_description = models.CharField()
|
|
270
|
+
specimen_source_coding_system = models.CharField()
|
|
271
|
+
order = models.ForeignKey(
|
|
272
|
+
LabOrder, on_delete=models.DO_NOTHING, related_name="tests", null=True
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
def __str__(self) -> str:
|
|
276
|
+
return f"{self.ontology_test_name}: f{self.ontology_test_code}"
|
canvas_sdk/v1/data/patient.py
CHANGED
|
@@ -49,4 +49,7 @@ class Patient(models.Model):
|
|
|
49
49
|
@classmethod
|
|
50
50
|
def find(cls, id: str) -> Self:
|
|
51
51
|
"""Find a patient by id."""
|
|
52
|
-
return cls.
|
|
52
|
+
return cls._default_manager.get(id=id)
|
|
53
|
+
|
|
54
|
+
def __str__(self) -> str:
|
|
55
|
+
return f"{self.first_name} {self.last_name}"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from canvas_sdk.v1.data.base import CommittableModelManager
|
|
4
|
+
from canvas_sdk.v1.data.patient import Patient
|
|
5
|
+
from canvas_sdk.v1.data.user import CanvasUser
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IntervalUnit(models.TextChoices):
|
|
9
|
+
"""ProtocolOverride cycle IntervalUnit."""
|
|
10
|
+
|
|
11
|
+
DAYS = "days", "days"
|
|
12
|
+
MONTHS = "months", "months"
|
|
13
|
+
YEARS = "years", "years"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Status(models.TextChoices):
|
|
17
|
+
"""ProtocolOverride Status."""
|
|
18
|
+
|
|
19
|
+
ACTIVE = "active", "active"
|
|
20
|
+
INACTIVE = "inactive", "inactive"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ProtocolOverride(models.Model):
|
|
24
|
+
"""ProtocolOverride."""
|
|
25
|
+
|
|
26
|
+
class Meta:
|
|
27
|
+
managed = False
|
|
28
|
+
app_label = "canvas_sdk"
|
|
29
|
+
db_table = "canvas_sdk_data_api_protocoloverride_001"
|
|
30
|
+
|
|
31
|
+
objects = CommittableModelManager()
|
|
32
|
+
|
|
33
|
+
id = models.UUIDField()
|
|
34
|
+
dbid = models.BigIntegerField(primary_key=True)
|
|
35
|
+
created = models.DateTimeField()
|
|
36
|
+
modified = models.DateTimeField()
|
|
37
|
+
deleted = models.BooleanField()
|
|
38
|
+
committer = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
39
|
+
entered_in_error = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
|
|
40
|
+
patient = models.ForeignKey(
|
|
41
|
+
Patient,
|
|
42
|
+
on_delete=models.DO_NOTHING,
|
|
43
|
+
related_name="allergy_intolerances",
|
|
44
|
+
)
|
|
45
|
+
protocol_key = models.CharField()
|
|
46
|
+
is_adjustment = models.BooleanField()
|
|
47
|
+
reference_date = models.DateTimeField()
|
|
48
|
+
cycle_in_days = models.IntegerField()
|
|
49
|
+
is_snooze = models.BooleanField()
|
|
50
|
+
snooze_date = models.DateField()
|
|
51
|
+
snoozed_days = models.IntegerField()
|
|
52
|
+
# reason_id = models.BigIntegerField()
|
|
53
|
+
snooze_comment = models.TextField()
|
|
54
|
+
narrative = models.CharField()
|
|
55
|
+
# note_id = models.BigIntegerField()
|
|
56
|
+
cycle_quantity = models.IntegerField()
|
|
57
|
+
cycle_unit = models.CharField(choices=IntervalUnit.choices)
|
|
58
|
+
status = models.CharField(choices=Status.choices)
|
|
@@ -109,7 +109,7 @@ class Questionnaire(models.Model):
|
|
|
109
109
|
code_system = models.CharField()
|
|
110
110
|
code = models.CharField()
|
|
111
111
|
search_tags = models.CharField()
|
|
112
|
-
questions = models.ManyToManyField(Question, through="QuestionnaireQuestionMap")
|
|
112
|
+
questions = models.ManyToManyField(Question, through="canvas_sdk.QuestionnaireQuestionMap") # type: ignore[misc, var-annotated]
|
|
113
113
|
use_in_shx = models.BooleanField()
|
|
114
114
|
carry_forward = models.TextField()
|
|
115
115
|
|
|
@@ -152,7 +152,9 @@ class Interview(models.Model):
|
|
|
152
152
|
patient = models.ForeignKey(Patient, on_delete=models.DO_NOTHING, related_name="interviews")
|
|
153
153
|
note_id = models.BigIntegerField()
|
|
154
154
|
appointment_id = models.BigIntegerField()
|
|
155
|
-
questionnaires = models.ManyToManyField(
|
|
155
|
+
questionnaires = models.ManyToManyField( # type: ignore[var-annotated]
|
|
156
|
+
Questionnaire, through="canvas_sdk.InterviewQuestionnaireMap" # type: ignore[misc]
|
|
157
|
+
)
|
|
156
158
|
progress_status = models.CharField()
|
|
157
159
|
created = models.DateTimeField()
|
|
158
160
|
modified = models.DateTimeField()
|
|
File without changes
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
1
|
from canvas_sdk.value_set.v2022.condition import (
|
|
4
2
|
DisordersOfTheImmuneSystem,
|
|
5
3
|
EncephalopathyDueToChildhoodVaccination,
|
|
6
4
|
Rhabdomyolysis,
|
|
7
5
|
StableAndUnstableAngina,
|
|
8
6
|
)
|
|
7
|
+
from canvas_sdk.value_set.value_set import CombinedValueSet
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def test_value_set_class_values_property() -> None:
|
|
@@ -15,7 +14,9 @@ def test_value_set_class_values_property() -> None:
|
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
def test_value_set_class_pipe_operator_with_two_value_sets() -> None:
|
|
18
|
-
combined_value_set =
|
|
17
|
+
combined_value_set: CombinedValueSet = (
|
|
18
|
+
DisordersOfTheImmuneSystem | EncephalopathyDueToChildhoodVaccination
|
|
19
|
+
)
|
|
19
20
|
|
|
20
21
|
both_classes_icd_10_codes = DisordersOfTheImmuneSystem.ICD10CM.union(
|
|
21
22
|
EncephalopathyDueToChildhoodVaccination.ICD10CM
|
|
@@ -29,7 +30,7 @@ def test_value_set_class_pipe_operator_with_two_value_sets() -> None:
|
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def test_value_set_class_pipe_operator_with_three_value_sets() -> None:
|
|
32
|
-
combined_value_set = (
|
|
33
|
+
combined_value_set: CombinedValueSet = (
|
|
33
34
|
DisordersOfTheImmuneSystem | EncephalopathyDueToChildhoodVaccination | Rhabdomyolysis
|
|
34
35
|
)
|
|
35
36
|
|
|
@@ -45,8 +46,10 @@ def test_value_set_class_pipe_operator_with_three_value_sets() -> None:
|
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
def test_value_set_class_pipe_operator_with_two_combined_value_sets() -> None:
|
|
48
|
-
combined_value_set_1 =
|
|
49
|
-
|
|
49
|
+
combined_value_set_1: CombinedValueSet = (
|
|
50
|
+
DisordersOfTheImmuneSystem | EncephalopathyDueToChildhoodVaccination
|
|
51
|
+
)
|
|
52
|
+
combined_value_set_2: CombinedValueSet = Rhabdomyolysis | StableAndUnstableAngina
|
|
50
53
|
|
|
51
54
|
combined_value_set = combined_value_set_1 | combined_value_set_2
|
|
52
55
|
|
|
File without changes
|