canvas 0.5.0__py3-none-any.whl → 0.7.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.

Files changed (38) hide show
  1. {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/METADATA +4 -3
  2. {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/RECORD +32 -31
  3. canvas_generated/messages/events_pb2.py +2 -2
  4. canvas_generated/messages/events_pb2.pyi +4 -0
  5. canvas_sdk/base.py +12 -9
  6. canvas_sdk/commands/base.py +2 -1
  7. canvas_sdk/effects/banner_alert/add_banner_alert.py +13 -2
  8. canvas_sdk/effects/banner_alert/remove_banner_alert.py +2 -2
  9. canvas_sdk/effects/banner_alert/tests.py +20 -4
  10. canvas_sdk/effects/base.py +2 -0
  11. canvas_sdk/effects/protocol_card/protocol_card.py +9 -2
  12. canvas_sdk/effects/protocol_card/tests.py +3 -3
  13. canvas_sdk/effects/task/task.py +99 -0
  14. canvas_sdk/protocols/base.py +1 -11
  15. canvas_sdk/protocols/clinical_quality_measure.py +57 -1
  16. canvas_sdk/protocols/timeframe.py +39 -0
  17. canvas_sdk/v1/data/__init__.py +3 -0
  18. canvas_sdk/v1/data/base.py +95 -12
  19. canvas_sdk/v1/data/billing.py +59 -0
  20. canvas_sdk/v1/data/common.py +58 -0
  21. canvas_sdk/v1/data/condition.py +18 -2
  22. canvas_sdk/v1/data/medication.py +11 -3
  23. canvas_sdk/v1/data/note.py +161 -0
  24. canvas_sdk/v1/data/patient.py +19 -1
  25. canvas_sdk/v1/data/protocol_override.py +1 -1
  26. canvas_sdk/v1/data/staff.py +65 -0
  27. canvas_sdk/v1/data/task.py +112 -0
  28. canvas_sdk/value_set/custom.py +984 -0
  29. canvas_sdk/value_set/value_set.py +4 -1
  30. plugin_runner/sandbox.py +3 -0
  31. canvas_sdk/data/__init__.py +0 -1
  32. canvas_sdk/data/base.py +0 -26
  33. canvas_sdk/data/client.py +0 -82
  34. canvas_sdk/data/patient.py +0 -8
  35. canvas_sdk/data/staff.py +0 -8
  36. canvas_sdk/data/task.py +0 -67
  37. {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/WHEEL +0 -0
  38. {canvas-0.5.0.dist-info → canvas-0.7.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,161 @@
1
+ from django.contrib.postgres.fields import ArrayField
2
+ from django.db import models
3
+
4
+ from canvas_sdk.v1.data.patient import Patient
5
+
6
+ # from canvas_sdk.v1.data.staff import Staff
7
+ from canvas_sdk.v1.data.user import CanvasUser
8
+
9
+
10
+ class NoteTypeCategories(models.TextChoices):
11
+ """Note type categories."""
12
+
13
+ MESSAGE = "message", "Message"
14
+ LETTER = "letter", "Letter"
15
+ INPATIENT = "inpatient", "Inpatient Visit Note"
16
+ REVIEW = "review", "Chart Review Note"
17
+ ENCOUNTER = "encounter", "Encounter Note"
18
+ APPOINTMENT = "appointment", "Appointment Note"
19
+ TASK = "task", "Task"
20
+ DATA = "data", "Data"
21
+ CCDA = "ccda", "C-CDA"
22
+ SCHEDULE_EVENT = "schedule_event", "Schedule Event"
23
+
24
+
25
+ class PracticeLocationPOS(models.TextChoices):
26
+ """Practice Location POS."""
27
+
28
+ PHARMACY = "01", "Pharmacy"
29
+ TELEHEALTH = "02", "Telehealth"
30
+ SCHOOL = "03", "Education Facility"
31
+ HOMELESS_SHELTER = "04", "Homeless Shelter"
32
+ PRISON = "09", "Prison"
33
+ TELEHEALTH_IN_PATIENT_HOME = "10", "Telehealth in Patient's Home"
34
+ OFFICE = "11", "Office"
35
+ HOME = "12", "Home"
36
+ ASSISTED_LIVING = "13", "Asssisted Living Facility"
37
+ GROUP_HOME = "14", "Group Home"
38
+ MOBILE = "15", "Mobile Unit"
39
+ WALK_IN_RETAIL = "17", "Walk-In Retail Health Clinic"
40
+ OFF_CAMPUS_OUTPATIENT_HOSPITAL = "19", "Off-Campus Outpatient Hospital"
41
+ URGENT_CARE = "20", "Urgent Care Facility"
42
+ INPATIENT_HOSPITAL = "21", "Inpatient Hospital"
43
+ ON_CAMPUS_OUTPATIENT_HOSPITAL = "22", "On-Campus Outpatient Hospital"
44
+ ER_HOSPITAL = "23", "Emergency Room Hospital"
45
+ AMBULATORY_SURGERY_CENTER = "24", "Ambulatory Surgery Center"
46
+ BIRTHING_CENTER = "25", "Birthing Center"
47
+ MILITARY_FACILITY = "26", "Military Treatment Facility"
48
+ STREET = "27", "Outreach Site / Street"
49
+ SNF = "31", "Skilled Nursing Facility"
50
+ NURSING = "32", "Nursing Facility"
51
+ CUSTODIAL = "33", "Custodial Care Facility"
52
+ HOSPICE = "34", "Hospice"
53
+ AMBULANCE_LAND = "41", "Ambulance Land"
54
+ AMBULANCE_AIR_WATER = "42", "Ambulance Air or Water"
55
+ INDEPENDENT_CLINIC = "49", "Independent Clinic"
56
+ FQHC = "50", "Federally Qualified Health Center"
57
+ PSYCH = "51", "Inpatient Psychiatric Facility"
58
+ PSYCH_PARTIAL = "52", "Inpatient Psychiatric Facility - Partial Hospitalization"
59
+ MENTAL_HEALTH_CENTER = "53", "Community Mental Health Center"
60
+ INTERMEDIATE_MENTAL = "54", "Intermediate Care Facility for Mentally Retarded"
61
+ SUBSTANCE_RESIDENTIAL = "55", "Residential Substance Abuse Treatment Facility"
62
+ PSYCH_RESIDENTIAL = "56", "Psychiatric Residential Treatment Center"
63
+ SUBSTANCE_NON_RESIDENTIAL = "57", "Non-Residential Substance Abuse Treatment Facility"
64
+ MASS_IMMUNIZATION = "60", "Mass Immunization Center"
65
+ INPATIENT_REHAB = "61", "Inpatient Rehabilitation Facility"
66
+ OUTPATIENT_REHAB = "62", "Outpatient Rehabilitation Facility"
67
+ ESRD = "65", "End-Stage Renal Disease Treatment Facility"
68
+ PUBLIC_CLINIC = "71", "State or Local Public Health Clinic"
69
+ RURAL_CLINIC = "72", "Rural Health Clinic"
70
+ INDEPENDENT_LAB = "81", "Independent Laboratory"
71
+ OTHER = "99", "Other Place of Service"
72
+
73
+
74
+ class NoteTypes(models.TextChoices):
75
+ """Note types."""
76
+
77
+ MESSAGE = "message", "Message"
78
+ LETTER = "letter", "Letter"
79
+ INPATIENT = "inpatient", "Inpatient Visit Note"
80
+ REVIEW = "review", "Chart Review Note"
81
+ VOICE = "voice", "Phone Call Note"
82
+ VIDEO = "video", "Video Call Note"
83
+ OFFICE = "office", "Office Visit Note"
84
+ LAB = "lab", "Lab Visit Note"
85
+ HOME = "home", "Home Visit Note"
86
+ GROUP = "group", "Group Visit Note"
87
+ APPOINTMENT = "appointment", "Appointment Note"
88
+ OFFSITE = "offsite", "Other Offsite Visit Note"
89
+ SEARCH = "search", "Search"
90
+ TASK = "task", "Task"
91
+ DATA = "data", "Data"
92
+ CCDA = "ccda", "C-CDA Import"
93
+
94
+
95
+ class NoteType(models.Model):
96
+ """NoteType."""
97
+
98
+ class Meta:
99
+ managed = False
100
+ app_label = "canvas_sdk"
101
+ db_table = "canvas_sdk_data_api_notetype_001"
102
+
103
+ dbid = models.BigIntegerField(primary_key=True)
104
+ created = models.DateTimeField()
105
+ modified = models.DateTimeField()
106
+ system = models.CharField()
107
+ version = models.CharField()
108
+ code = models.CharField()
109
+ display = models.CharField()
110
+ user_selected = models.BooleanField()
111
+ name = models.CharField()
112
+ icon = models.CharField()
113
+ category = models.CharField(choices=NoteTypeCategories.choices)
114
+ rank = models.PositiveIntegerField()
115
+ is_default_appointment_type = models.BooleanField()
116
+ is_scheduleable = models.BooleanField()
117
+ is_telehealth = models.BooleanField()
118
+ is_billable = models.BooleanField()
119
+ defer_place_of_service_to_practice_location = models.BooleanField()
120
+ available_places_of_service = ArrayField(models.CharField(choices=PracticeLocationPOS.choices))
121
+ default_place_of_service = models.CharField(choices=PracticeLocationPOS.choices)
122
+ is_system_managed = models.BooleanField()
123
+ is_visible = models.BooleanField()
124
+ is_active = models.BooleanField()
125
+ unique_identifier = models.UUIDField()
126
+ deprecated_at = models.DateTimeField()
127
+ is_patient_required = models.BooleanField()
128
+ allow_custom_title = models.BooleanField()
129
+
130
+
131
+ class Note(models.Model):
132
+ """Note."""
133
+
134
+ class Meta:
135
+ managed = False
136
+ app_label = "canvas_sdk"
137
+ db_table = "canvas_sdk_data_api_note_001"
138
+
139
+ id = models.CharField(max_length=32)
140
+ dbid = models.BigIntegerField(db_column="dbid", primary_key=True)
141
+ created = models.DateTimeField()
142
+ modified = models.DateTimeField()
143
+ patient = models.ForeignKey(Patient, on_delete=models.DO_NOTHING)
144
+ # provider = models.ForeignKey(Staff, on_delete=models.DO_NOTHING, related_name="notes")
145
+ note_type = models.CharField(choices=NoteTypes.choices, null=True)
146
+ note_type_version = models.ForeignKey(
147
+ "NoteType", on_delete=models.DO_NOTHING, related_name="notes"
148
+ )
149
+ title = models.TextField()
150
+ body = models.JSONField()
151
+ originator = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
152
+ # last_modified_by_staff = models.ForeignKey(Staff, on_delete=models.DO_NOTHING, null=True)
153
+ checksum = models.CharField()
154
+ billing_note = models.TextField()
155
+ # TODO -implement InpatientStay model
156
+ # inpatient_stay = models.ForeignKey("InpatientStay", on_delete=models.DO_NOTHING)
157
+ related_data = models.JSONField()
158
+ # TODO -implement PracticeLocation model
159
+ # location = models.ForeignKey(PracticeLocation, on_delete=models.DO_NOTHING)
160
+ datetime_of_service = models.DateTimeField()
161
+ place_of_service = models.CharField()
@@ -1,5 +1,6 @@
1
- from typing import Self
1
+ from typing import TYPE_CHECKING, Self
2
2
 
3
+ import arrow
3
4
  from django.db import models
4
5
 
5
6
 
@@ -53,3 +54,20 @@ class Patient(models.Model):
53
54
 
54
55
  def __str__(self) -> str:
55
56
  return f"{self.first_name} {self.last_name}"
57
+
58
+ def age_at(self, time: arrow.Arrow) -> float:
59
+ """Given a datetime, returns what the patient's age would be at that datetime."""
60
+ age = float(0)
61
+ birth_date = arrow.get(self.birth_date)
62
+ if birth_date.date() < time.date():
63
+ age = time.datetime.year - birth_date.datetime.year
64
+ if time.datetime.month < birth_date.datetime.month or (
65
+ time.datetime.month == birth_date.datetime.month
66
+ and time.datetime.day < birth_date.datetime.day
67
+ ):
68
+ age -= 1
69
+
70
+ current_year = birth_date.shift(years=age)
71
+ next_year = birth_date.shift(years=age + 1)
72
+ age += (time.date() - current_year.date()) / (next_year.date() - current_year.date())
73
+ return age
@@ -40,7 +40,7 @@ class ProtocolOverride(models.Model):
40
40
  patient = models.ForeignKey(
41
41
  Patient,
42
42
  on_delete=models.DO_NOTHING,
43
- related_name="allergy_intolerances",
43
+ related_name="protocol_overrides",
44
44
  )
45
45
  protocol_key = models.CharField()
46
46
  is_adjustment = models.BooleanField()
@@ -0,0 +1,65 @@
1
+ from django.contrib.postgres.fields import ArrayField
2
+ from django.db import models
3
+ from timezone_utils.fields import TimeZoneField
4
+
5
+ from canvas_sdk.v1.data.common import PersonSex, TaxIDType
6
+ from canvas_sdk.v1.data.user import CanvasUser
7
+
8
+
9
+ class Staff(models.Model):
10
+ """Staff."""
11
+
12
+ class Meta:
13
+ managed = False
14
+ app_label = "canvas_sdk"
15
+ db_table = "canvas_sdk_data_api_staff_001"
16
+
17
+ def __str__(self) -> str:
18
+ return f"{self.first_name} {self.last_name}"
19
+
20
+ id = models.CharField(max_length=32, db_column="key")
21
+ dbid = models.BigIntegerField(db_column="dbid", primary_key=True)
22
+ created = models.DateTimeField()
23
+ modified = models.DateTimeField()
24
+ prefix = models.CharField()
25
+ suffix = models.CharField()
26
+ first_name = models.CharField()
27
+ middle_name = models.CharField()
28
+ last_name = models.CharField()
29
+ maiden_name = models.CharField()
30
+ nickname = models.CharField()
31
+ previous_names = models.JSONField()
32
+ birth_date = models.DateField(null=True)
33
+ sex_at_birth = models.CharField(choices=PersonSex.choices)
34
+ sexual_orientation_term = models.CharField()
35
+ sexual_orientation_code = models.CharField()
36
+ gender_identity_term = models.CharField()
37
+ gender_identity_code = models.CharField()
38
+ preferred_pronouns = models.CharField()
39
+ biological_race_codes = ArrayField(models.CharField())
40
+ biological_race_terms = ArrayField(models.CharField())
41
+ cultural_ethnicity_codes = ArrayField(models.CharField())
42
+ cultural_ethnicity_terms = ArrayField(models.CharField())
43
+ last_known_timezone = TimeZoneField(null=True)
44
+ active = models.BooleanField()
45
+ # TODO - uncomment when PracticeLocation field is developed
46
+ # primary_practice_location = models.ForeignKey(
47
+ # PracticeLocation, on_delete=models.DO_NOTHING, null=True
48
+ # )
49
+ npi_number = models.CharField()
50
+ nadean_number = models.CharField()
51
+ group_npi_number = models.CharField()
52
+ bill_through_organization = models.BooleanField()
53
+ tax_id = models.CharField()
54
+ tax_id_type = models.CharField(choices=TaxIDType.choices)
55
+ spi_number = models.CharField()
56
+ # TODO - uncomment when Language is developed
57
+ # language = models.ForeignKey(Language, on_delete=models.DO_NOTHING, related_name="staff_speakers")
58
+ # language_secondary = models.ForeignKey(Language, on_delete=models.DO_NOTHING, related_name="staff_secondary_speakers")
59
+ personal_meeting_room_link = models.URLField(null=True)
60
+ state = models.JSONField()
61
+ user = models.ForeignKey(CanvasUser, on_delete=models.DO_NOTHING)
62
+ schedule_column_ordering = models.IntegerField()
63
+ default_supervising_provider = models.ForeignKey(
64
+ "Staff", on_delete=models.DO_NOTHING, null=True, related_name="supervising_team"
65
+ )
@@ -0,0 +1,112 @@
1
+ from django.contrib.postgres.fields import ArrayField
2
+ from django.db import models
3
+
4
+ from canvas_sdk.v1.data.common import ColorEnum, Origin
5
+ from canvas_sdk.v1.data.patient import Patient
6
+ from canvas_sdk.v1.data.staff import Staff
7
+
8
+
9
+ class TaskType(models.TextChoices):
10
+ """Choices for task types."""
11
+
12
+ TASK = "Task", "Task"
13
+ REMINDER = "Reminder", "Reminder"
14
+
15
+
16
+ class EventType(models.TextChoices):
17
+ """Choices for event types."""
18
+
19
+ EVENT_CHART_OPEN = "Chart Open", "Chart Open"
20
+
21
+
22
+ class TaskStatus(models.TextChoices):
23
+ """Choices for task statuses."""
24
+
25
+ COMPLETED = "COMPLETED", "Completed"
26
+ CLOSED = "CLOSED", "Closed"
27
+ OPEN = "OPEN", "Open"
28
+
29
+
30
+ class TaskLabelModule(models.TextChoices):
31
+ """Choices for task label modules."""
32
+
33
+ CLAIMS = "claims", "Claims"
34
+ TASKS = "tasks", "Tasks"
35
+
36
+
37
+ class Task(models.Model):
38
+ """Task."""
39
+
40
+ class Meta:
41
+ managed = False
42
+ app_label = "canvas_sdk"
43
+ db_table = "canvas_sdk_data_api_task_001"
44
+
45
+ id = models.UUIDField()
46
+ dbid = models.BigIntegerField(primary_key=True)
47
+ created = models.DateTimeField()
48
+ modified = models.DateTimeField()
49
+ creator = models.ForeignKey(Staff, related_name="creator_tasks", on_delete=models.DO_NOTHING)
50
+ assignee = models.ForeignKey(
51
+ Staff, related_name="assignee_tasks", null=True, on_delete=models.DO_NOTHING
52
+ )
53
+ # TODO - uncomment when Team model is created
54
+ # team = models.ForeignKey(Team, related_name="tasks", null=True, on_delete=models.DO_NOTHING)
55
+ patient = models.ForeignKey(
56
+ Patient, blank=True, null=True, on_delete=models.DO_NOTHING, related_name="tasks"
57
+ )
58
+ task_type = models.CharField(choices=TaskType.choices)
59
+ tag = models.CharField()
60
+ title = models.CharField()
61
+ due = models.DateTimeField(null=True)
62
+ due_event = models.CharField(choices=EventType.choices, blank=True)
63
+ status = models.CharField(choices=TaskStatus.choices)
64
+
65
+
66
+ class TaskComment(models.Model):
67
+ """TaskComment."""
68
+
69
+ class Meta:
70
+ managed = False
71
+ app_label = "canvas_sdk"
72
+ db_table = "canvas_sdk_data_api_taskcomment_001"
73
+
74
+ id = models.UUIDField()
75
+ dbid = models.BigIntegerField(primary_key=True)
76
+ created = models.DateTimeField()
77
+ modified = models.DateTimeField()
78
+ creator = models.ForeignKey(Staff, related_name="comments", on_delete=models.DO_NOTHING)
79
+ task = models.ForeignKey(Task, on_delete=models.DO_NOTHING, related_name="comments")
80
+ body = models.TextField()
81
+
82
+
83
+ class TaskLabel(models.Model):
84
+ """TaskLabel."""
85
+
86
+ class Meta:
87
+ managed = False
88
+ app_label = "canvas_sdk"
89
+ db_table = "canvas_sdk_data_api_tasklabel_001"
90
+
91
+ id = models.UUIDField()
92
+ dbid = models.BigIntegerField(primary_key=True)
93
+ tasks = models.ManyToManyField(Task, related_name="labels", through="TaskTaskLabel") # type: ignore[var-annotated]
94
+ position = models.IntegerField()
95
+ color = models.CharField(choices=ColorEnum.choices)
96
+ task_association = ArrayField(models.CharField(choices=Origin.choices))
97
+ name = models.CharField()
98
+ active = models.BooleanField()
99
+ modules = ArrayField(models.CharField(choices=TaskLabelModule.choices))
100
+
101
+
102
+ class TaskTaskLabel(models.Model):
103
+ """M2M for Task -> TaskLabels."""
104
+
105
+ class Meta:
106
+ managed = False
107
+ app_label = "canvas_sdk"
108
+ db_table = "canvas_sdk_data_api_tasktasklabel_001"
109
+
110
+ dbid = models.BigIntegerField(primary_key=True)
111
+ task_label = models.ForeignKey(TaskLabel, on_delete=models.DO_NOTHING)
112
+ task = models.ForeignKey(Task, on_delete=models.DO_NOTHING)