canvas 0.63.0__py3-none-any.whl → 0.89.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.
Files changed (185) hide show
  1. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/METADATA +4 -1
  2. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/RECORD +184 -98
  3. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/WHEEL +1 -1
  4. canvas_cli/apps/emit/event_fixtures/UNKNOWN.ndjson +1 -0
  5. canvas_cli/apps/logs/logs.py +386 -22
  6. canvas_cli/main.py +3 -1
  7. canvas_cli/templates/plugins/default/{{ cookiecutter.__project_slug }}/tests/test_models.py +46 -4
  8. canvas_cli/utils/context/context.py +13 -13
  9. canvas_cli/utils/validators/manifest_schema.py +26 -1
  10. canvas_generated/messages/effects_pb2.py +5 -5
  11. canvas_generated/messages/effects_pb2.pyi +108 -2
  12. canvas_generated/messages/events_pb2.py +6 -6
  13. canvas_generated/messages/events_pb2.pyi +282 -2
  14. canvas_sdk/clients/__init__.py +1 -0
  15. canvas_sdk/clients/llms/__init__.py +17 -0
  16. canvas_sdk/clients/llms/libraries/__init__.py +11 -0
  17. canvas_sdk/clients/llms/libraries/llm_anthropic.py +87 -0
  18. canvas_sdk/clients/llms/libraries/llm_api.py +143 -0
  19. canvas_sdk/clients/llms/libraries/llm_google.py +92 -0
  20. canvas_sdk/clients/llms/libraries/llm_openai.py +98 -0
  21. canvas_sdk/clients/llms/structures/__init__.py +9 -0
  22. canvas_sdk/clients/llms/structures/llm_response.py +33 -0
  23. canvas_sdk/clients/llms/structures/llm_tokens.py +53 -0
  24. canvas_sdk/clients/llms/structures/llm_turn.py +47 -0
  25. canvas_sdk/clients/llms/structures/settings/__init__.py +13 -0
  26. canvas_sdk/clients/llms/structures/settings/llm_settings.py +27 -0
  27. canvas_sdk/clients/llms/structures/settings/llm_settings_anthropic.py +43 -0
  28. canvas_sdk/clients/llms/structures/settings/llm_settings_gemini.py +40 -0
  29. canvas_sdk/clients/llms/structures/settings/llm_settings_gpt4.py +40 -0
  30. canvas_sdk/clients/llms/structures/settings/llm_settings_gpt5.py +48 -0
  31. canvas_sdk/clients/third_party.py +3 -0
  32. canvas_sdk/commands/__init__.py +12 -0
  33. canvas_sdk/commands/base.py +33 -2
  34. canvas_sdk/commands/commands/adjust_prescription.py +4 -0
  35. canvas_sdk/commands/commands/custom_command.py +86 -0
  36. canvas_sdk/commands/commands/family_history.py +17 -1
  37. canvas_sdk/commands/commands/immunization_statement.py +42 -2
  38. canvas_sdk/commands/commands/medication_statement.py +16 -1
  39. canvas_sdk/commands/commands/past_surgical_history.py +16 -1
  40. canvas_sdk/commands/commands/perform.py +18 -1
  41. canvas_sdk/commands/commands/prescribe.py +8 -9
  42. canvas_sdk/commands/commands/refill.py +5 -5
  43. canvas_sdk/commands/commands/resolve_condition.py +5 -5
  44. canvas_sdk/commands/commands/review/__init__.py +3 -0
  45. canvas_sdk/commands/commands/review/base.py +72 -0
  46. canvas_sdk/commands/commands/review/imaging.py +13 -0
  47. canvas_sdk/commands/commands/review/lab.py +13 -0
  48. canvas_sdk/commands/commands/review/referral.py +13 -0
  49. canvas_sdk/commands/commands/review/uncategorized_document.py +13 -0
  50. canvas_sdk/commands/validation.py +43 -0
  51. canvas_sdk/effects/batch_originate.py +22 -0
  52. canvas_sdk/effects/calendar/__init__.py +13 -3
  53. canvas_sdk/effects/calendar/{create_calendar.py → calendar.py} +19 -5
  54. canvas_sdk/effects/calendar/event.py +172 -0
  55. canvas_sdk/effects/claim_label.py +93 -0
  56. canvas_sdk/effects/claim_line_item.py +47 -0
  57. canvas_sdk/effects/claim_queue.py +49 -0
  58. canvas_sdk/effects/fax/__init__.py +3 -0
  59. canvas_sdk/effects/fax/base.py +77 -0
  60. canvas_sdk/effects/fax/note.py +42 -0
  61. canvas_sdk/effects/metadata.py +15 -1
  62. canvas_sdk/effects/note/__init__.py +8 -1
  63. canvas_sdk/effects/note/appointment.py +135 -7
  64. canvas_sdk/effects/note/base.py +17 -0
  65. canvas_sdk/effects/note/message.py +22 -14
  66. canvas_sdk/effects/note/note.py +150 -1
  67. canvas_sdk/effects/observation/__init__.py +11 -0
  68. canvas_sdk/effects/observation/base.py +206 -0
  69. canvas_sdk/effects/patient/__init__.py +2 -0
  70. canvas_sdk/effects/patient/base.py +8 -0
  71. canvas_sdk/effects/payment/__init__.py +11 -0
  72. canvas_sdk/effects/payment/base.py +355 -0
  73. canvas_sdk/effects/payment/post_claim_payment.py +49 -0
  74. canvas_sdk/effects/send_contact_verification.py +42 -0
  75. canvas_sdk/effects/task/__init__.py +2 -1
  76. canvas_sdk/effects/task/task.py +30 -0
  77. canvas_sdk/effects/validation/__init__.py +3 -0
  78. canvas_sdk/effects/validation/base.py +92 -0
  79. canvas_sdk/events/base.py +15 -0
  80. canvas_sdk/handlers/application.py +7 -7
  81. canvas_sdk/handlers/simple_api/api.py +1 -4
  82. canvas_sdk/handlers/simple_api/websocket.py +1 -4
  83. canvas_sdk/handlers/utils.py +14 -0
  84. canvas_sdk/questionnaires/utils.py +1 -0
  85. canvas_sdk/templates/utils.py +17 -4
  86. canvas_sdk/test_utils/factories/FACTORY_GUIDE.md +362 -0
  87. canvas_sdk/test_utils/factories/__init__.py +115 -0
  88. canvas_sdk/test_utils/factories/calendar.py +24 -0
  89. canvas_sdk/test_utils/factories/claim.py +81 -0
  90. canvas_sdk/test_utils/factories/claim_diagnosis_code.py +16 -0
  91. canvas_sdk/test_utils/factories/coverage.py +17 -0
  92. canvas_sdk/test_utils/factories/imaging.py +74 -0
  93. canvas_sdk/test_utils/factories/lab.py +192 -0
  94. canvas_sdk/test_utils/factories/medication_history.py +75 -0
  95. canvas_sdk/test_utils/factories/note.py +52 -0
  96. canvas_sdk/test_utils/factories/organization.py +50 -0
  97. canvas_sdk/test_utils/factories/practicelocation.py +88 -0
  98. canvas_sdk/test_utils/factories/referral.py +81 -0
  99. canvas_sdk/test_utils/factories/staff.py +111 -0
  100. canvas_sdk/test_utils/factories/task.py +66 -0
  101. canvas_sdk/test_utils/factories/uncategorized_clinical_document.py +48 -0
  102. canvas_sdk/utils/metrics.py +4 -1
  103. canvas_sdk/v1/data/__init__.py +66 -7
  104. canvas_sdk/v1/data/allergy_intolerance.py +5 -11
  105. canvas_sdk/v1/data/appointment.py +18 -4
  106. canvas_sdk/v1/data/assessment.py +2 -12
  107. canvas_sdk/v1/data/banner_alert.py +2 -4
  108. canvas_sdk/v1/data/base.py +53 -14
  109. canvas_sdk/v1/data/billing.py +8 -11
  110. canvas_sdk/v1/data/calendar.py +64 -0
  111. canvas_sdk/v1/data/care_team.py +4 -10
  112. canvas_sdk/v1/data/claim.py +172 -66
  113. canvas_sdk/v1/data/claim_diagnosis_code.py +19 -0
  114. canvas_sdk/v1/data/claim_line_item.py +2 -5
  115. canvas_sdk/v1/data/coding.py +19 -0
  116. canvas_sdk/v1/data/command.py +2 -4
  117. canvas_sdk/v1/data/common.py +10 -0
  118. canvas_sdk/v1/data/compound_medication.py +3 -4
  119. canvas_sdk/v1/data/condition.py +4 -9
  120. canvas_sdk/v1/data/coverage.py +66 -26
  121. canvas_sdk/v1/data/detected_issue.py +20 -20
  122. canvas_sdk/v1/data/device.py +2 -14
  123. canvas_sdk/v1/data/discount.py +2 -5
  124. canvas_sdk/v1/data/encounter.py +44 -0
  125. canvas_sdk/v1/data/facility.py +1 -0
  126. canvas_sdk/v1/data/goal.py +2 -14
  127. canvas_sdk/v1/data/imaging.py +4 -30
  128. canvas_sdk/v1/data/immunization.py +7 -15
  129. canvas_sdk/v1/data/lab.py +12 -65
  130. canvas_sdk/v1/data/line_item_transaction.py +2 -5
  131. canvas_sdk/v1/data/medication.py +3 -8
  132. canvas_sdk/v1/data/medication_history.py +142 -0
  133. canvas_sdk/v1/data/medication_statement.py +41 -0
  134. canvas_sdk/v1/data/message.py +4 -8
  135. canvas_sdk/v1/data/note.py +37 -38
  136. canvas_sdk/v1/data/observation.py +9 -36
  137. canvas_sdk/v1/data/organization.py +70 -9
  138. canvas_sdk/v1/data/patient.py +8 -12
  139. canvas_sdk/v1/data/patient_consent.py +4 -14
  140. canvas_sdk/v1/data/payment_collection.py +2 -5
  141. canvas_sdk/v1/data/posting.py +3 -9
  142. canvas_sdk/v1/data/practicelocation.py +66 -7
  143. canvas_sdk/v1/data/protocol_override.py +3 -4
  144. canvas_sdk/v1/data/protocol_result.py +3 -3
  145. canvas_sdk/v1/data/questionnaire.py +10 -26
  146. canvas_sdk/v1/data/reason_for_visit.py +2 -6
  147. canvas_sdk/v1/data/referral.py +41 -17
  148. canvas_sdk/v1/data/staff.py +34 -26
  149. canvas_sdk/v1/data/stop_medication_event.py +27 -0
  150. canvas_sdk/v1/data/task.py +30 -11
  151. canvas_sdk/v1/data/team.py +2 -4
  152. canvas_sdk/v1/data/uncategorized_clinical_document.py +84 -0
  153. canvas_sdk/v1/data/user.py +14 -0
  154. canvas_sdk/v1/data/utils.py +5 -0
  155. canvas_sdk/value_set/v2026/__init__.py +1 -0
  156. canvas_sdk/value_set/v2026/adverse_event.py +157 -0
  157. canvas_sdk/value_set/v2026/allergy.py +116 -0
  158. canvas_sdk/value_set/v2026/assessment.py +466 -0
  159. canvas_sdk/value_set/v2026/communication.py +496 -0
  160. canvas_sdk/value_set/v2026/condition.py +52934 -0
  161. canvas_sdk/value_set/v2026/device.py +315 -0
  162. canvas_sdk/value_set/v2026/diagnostic_study.py +5243 -0
  163. canvas_sdk/value_set/v2026/encounter.py +2714 -0
  164. canvas_sdk/value_set/v2026/immunization.py +297 -0
  165. canvas_sdk/value_set/v2026/individual_characteristic.py +339 -0
  166. canvas_sdk/value_set/v2026/intervention.py +1703 -0
  167. canvas_sdk/value_set/v2026/laboratory_test.py +1831 -0
  168. canvas_sdk/value_set/v2026/medication.py +8218 -0
  169. canvas_sdk/value_set/v2026/no_qdm_category_assigned.py +26493 -0
  170. canvas_sdk/value_set/v2026/physical_exam.py +342 -0
  171. canvas_sdk/value_set/v2026/procedure.py +27869 -0
  172. canvas_sdk/value_set/v2026/symptom.py +625 -0
  173. logger/logger.py +30 -31
  174. logger/logstash.py +282 -0
  175. logger/pubsub.py +26 -0
  176. plugin_runner/allowed-module-imports.json +940 -9
  177. plugin_runner/generate_allowed_imports.py +1 -0
  178. plugin_runner/installation.py +2 -2
  179. plugin_runner/plugin_runner.py +21 -24
  180. plugin_runner/sandbox.py +34 -0
  181. protobufs/canvas_generated/messages/effects.proto +65 -0
  182. protobufs/canvas_generated/messages/events.proto +150 -51
  183. settings.py +27 -11
  184. canvas_sdk/effects/calendar/create_event.py +0 -43
  185. {canvas-0.63.0.dist-info → canvas-0.89.0.dist-info}/entry_points.txt +0 -0
@@ -3,17 +3,19 @@ from typing import cast
3
3
  from django.db import models
4
4
 
5
5
  from canvas_sdk.v1.data.base import (
6
+ AuditedModel,
6
7
  BaseModelManager,
7
8
  CommittableQuerySetMixin,
8
9
  ForPatientQuerySetMixin,
9
10
  IdentifiableModel,
10
- Model,
11
+ TimestampedModel,
11
12
  ValueSetLookupQuerySet,
12
13
  )
14
+ from canvas_sdk.v1.data.coding import Coding
13
15
 
14
16
 
15
17
  class ObservationQuerySet(
16
- ValueSetLookupQuerySet, CommittableQuerySetMixin, ForPatientQuerySetMixin
18
+ CommittableQuerySetMixin, ForPatientQuerySetMixin, ValueSetLookupQuerySet
17
19
  ):
18
20
  """ObservationQuerySet."""
19
21
 
@@ -23,7 +25,7 @@ class ObservationQuerySet(
23
25
  ObservationManager = BaseModelManager.from_queryset(ObservationQuerySet)
24
26
 
25
27
 
26
- class Observation(IdentifiableModel):
28
+ class Observation(AuditedModel, IdentifiableModel):
27
29
  """Observation."""
28
30
 
29
31
  class Meta:
@@ -31,18 +33,6 @@ class Observation(IdentifiableModel):
31
33
 
32
34
  objects = cast(ObservationQuerySet, ObservationManager())
33
35
 
34
- created = models.DateTimeField(auto_now_add=True)
35
- modified = models.DateTimeField(auto_now=True)
36
- originator = models.ForeignKey(
37
- "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
38
- )
39
- committer = models.ForeignKey(
40
- "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
41
- )
42
- entered_in_error = models.ForeignKey(
43
- "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
44
- )
45
- deleted = models.BooleanField()
46
36
  patient = models.ForeignKey(
47
37
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="observations", null=True
48
38
  )
@@ -57,30 +47,23 @@ class Observation(IdentifiableModel):
57
47
  effective_datetime = models.DateTimeField()
58
48
 
59
49
 
60
- class ObservationCoding(Model):
50
+ class ObservationCoding(Coding):
61
51
  """ObservationCoding."""
62
52
 
63
53
  class Meta:
64
54
  db_table = "canvas_sdk_data_api_observationcoding_001"
65
55
 
66
- system = models.CharField(max_length=255)
67
- version = models.CharField(max_length=255)
68
- code = models.CharField(max_length=255)
69
- display = models.CharField(max_length=1000)
70
- user_selected = models.BooleanField()
71
56
  observation = models.ForeignKey(
72
57
  Observation, on_delete=models.DO_NOTHING, related_name="codings", null=True
73
58
  )
74
59
 
75
60
 
76
- class ObservationComponent(Model):
61
+ class ObservationComponent(TimestampedModel):
77
62
  """ObservationComponent."""
78
63
 
79
64
  class Meta:
80
65
  db_table = "canvas_sdk_data_api_observationcomponent_001"
81
66
 
82
- created = models.DateTimeField(auto_now_add=True)
83
- modified = models.DateTimeField(auto_now=True)
84
67
  observation = models.ForeignKey(
85
68
  Observation, on_delete=models.DO_NOTHING, related_name="components", null=True
86
69
  )
@@ -89,33 +72,23 @@ class ObservationComponent(Model):
89
72
  name = models.TextField()
90
73
 
91
74
 
92
- class ObservationComponentCoding(Model):
75
+ class ObservationComponentCoding(Coding):
93
76
  """ObservationComponentCoding."""
94
77
 
95
78
  class Meta:
96
79
  db_table = "canvas_sdk_data_api_observationcomponentcoding_001"
97
80
 
98
- system = models.CharField(max_length=255)
99
- version = models.CharField(max_length=255)
100
- code = models.CharField(max_length=255)
101
- display = models.CharField(max_length=1000)
102
- user_selected = models.BooleanField()
103
81
  observation_component = models.ForeignKey(
104
82
  ObservationComponent, on_delete=models.DO_NOTHING, related_name="codings", null=True
105
83
  )
106
84
 
107
85
 
108
- class ObservationValueCoding(Model):
86
+ class ObservationValueCoding(Coding):
109
87
  """ObservationValueCoding."""
110
88
 
111
89
  class Meta:
112
90
  db_table = "canvas_sdk_data_api_observationvaluecoding_001"
113
91
 
114
- system = models.CharField(max_length=255)
115
- version = models.CharField(max_length=255)
116
- code = models.CharField(max_length=255)
117
- display = models.CharField(max_length=1000)
118
- user_selected = models.BooleanField()
119
92
  observation = models.ForeignKey(
120
93
  Observation, on_delete=models.DO_NOTHING, related_name="value_codings", null=True
121
94
  )
@@ -1,32 +1,93 @@
1
1
  from django.db import models
2
2
 
3
- from canvas_sdk.v1.data.base import Model
4
- from canvas_sdk.v1.data.common import TaxIDType
3
+ from canvas_sdk.v1.data.base import IdentifiableModel, TimestampedModel
4
+ from canvas_sdk.v1.data.common import (
5
+ AddressState,
6
+ AddressType,
7
+ AddressUseWithBilling,
8
+ ContactPointState,
9
+ ContactPointSystem,
10
+ ContactPointUse,
11
+ TaxIDType,
12
+ )
5
13
 
6
14
 
7
- class Organization(Model):
15
+ class Organization(TimestampedModel):
8
16
  """Organization."""
9
17
 
10
18
  class Meta:
11
19
  db_table = "canvas_sdk_data_api_organization_001"
12
20
 
13
- created = models.DateTimeField(auto_now_add=True)
14
- modified = models.DateTimeField(auto_now=True)
15
21
  full_name = models.CharField(max_length=255)
16
22
  short_name = models.CharField(max_length=255)
17
23
  subdomain = models.CharField(max_length=100)
18
24
  logo_url = models.CharField(max_length=255)
19
25
  background_image_url = models.CharField(max_length=255)
20
26
  background_gradient = models.CharField(max_length=255)
21
- active = models.BooleanField()
27
+ active = models.BooleanField(default=True)
22
28
  tax_id = models.CharField(null=True, max_length=25)
23
29
  tax_id_type = models.CharField(choices=TaxIDType.choices, max_length=1)
24
30
  group_npi_number = models.CharField(max_length=10)
25
31
  group_taxonomy_number = models.CharField(max_length=10)
26
- include_zz_qualifier = models.BooleanField()
32
+ include_zz_qualifier = models.BooleanField(default=False)
27
33
  main_location = models.OneToOneField(
28
- "v1.PracticeLocation", on_delete=models.DO_NOTHING, related_name="+"
34
+ "PracticeLocation", related_name="+", null=True, on_delete=models.PROTECT
29
35
  )
30
36
 
31
37
 
32
- __exports__ = ("Organization",)
38
+ class OrganizationAddress(IdentifiableModel):
39
+ """Organization Address."""
40
+
41
+ class Meta:
42
+ db_table = "canvas_sdk_data_api_organizationaddress_001"
43
+
44
+ organization = models.ForeignKey(
45
+ "v1.Organization", on_delete=models.PROTECT, related_name="addresses"
46
+ )
47
+ use = models.CharField(
48
+ choices=AddressUseWithBilling.choices, max_length=10, default=AddressUseWithBilling.HOME
49
+ )
50
+ type = models.CharField(choices=AddressType.choices, max_length=10, default=AddressType.BOTH)
51
+ longitude = models.FloatField(null=True, default=None, blank=True)
52
+ latitude = models.FloatField(null=True, default=None, blank=True)
53
+ start = models.DateField(null=True, blank=True)
54
+ end = models.DateField(null=True, blank=True)
55
+ country = models.CharField(max_length=255)
56
+ state = models.CharField(
57
+ choices=AddressState.choices, max_length=20, default=AddressState.ACTIVE
58
+ )
59
+ address_search_index = models.TextField(default="", null=True, blank=True)
60
+ line1 = models.CharField(max_length=255, default="", blank=True)
61
+ line2 = models.CharField(max_length=255, default="", blank=True)
62
+ city = models.CharField(max_length=255)
63
+ district = models.CharField(max_length=255, blank=True, default="")
64
+ state_code = models.CharField(max_length=2)
65
+ postal_code = models.CharField(max_length=255)
66
+
67
+
68
+ class OrganizationContactPoint(IdentifiableModel):
69
+ """OrganizationContactPoint."""
70
+
71
+ class Meta:
72
+ db_table = "canvas_sdk_data_api_organizationcontactpoint_001"
73
+
74
+ organization = models.ForeignKey(
75
+ "v1.Organization", on_delete=models.PROTECT, related_name="telecom"
76
+ )
77
+ system = models.CharField(choices=ContactPointSystem.choices, max_length=20, db_index=True)
78
+ value = models.CharField(max_length=100, db_index=True)
79
+ use = models.CharField(
80
+ choices=ContactPointUse.choices, max_length=20, default=ContactPointUse.HOME
81
+ )
82
+ use_notes = models.CharField(max_length=255, blank=True, default="")
83
+ rank = models.IntegerField(default=1)
84
+ state = models.CharField(
85
+ choices=ContactPointState.choices, max_length=20, default=ContactPointState.ACTIVE
86
+ )
87
+
88
+
89
+ __exports__ = (
90
+ "Organization",
91
+ "OrganizationAddress",
92
+ "OrganizationContactPoint",
93
+ )
@@ -7,7 +7,7 @@ from django.contrib.postgres.fields import ArrayField
7
7
  from django.db import models
8
8
  from django.db.models import TextChoices
9
9
 
10
- from canvas_sdk.v1.data.base import IdentifiableModel, Model
10
+ from canvas_sdk.v1.data.base import IdentifiableModel, TimestampedModel
11
11
  from canvas_sdk.v1.data.common import (
12
12
  AddressState,
13
13
  AddressType,
@@ -39,7 +39,7 @@ class PatientSettingConstants:
39
39
  PREFERRED_SCHEDULING_TIMEZONE = "preferredSchedulingTimezone"
40
40
 
41
41
 
42
- class Patient(Model):
42
+ class Patient(TimestampedModel):
43
43
  """A class representing a patient."""
44
44
 
45
45
  class Meta:
@@ -72,6 +72,9 @@ class Patient(Model):
72
72
  biological_race_codes = ArrayField(
73
73
  models.CharField(max_length=100, default="", blank=True), default=list, blank=True
74
74
  )
75
+ cultural_ethnicity_codes = ArrayField(
76
+ models.CharField(max_length=100, default="", blank=True), default=list, blank=True
77
+ )
75
78
  last_known_timezone = models.CharField(max_length=32, null=True, blank=True)
76
79
  mrn = models.CharField(max_length=9, unique=True, default=generate_mrn)
77
80
  active = models.BooleanField(default=True)
@@ -103,10 +106,7 @@ class Patient(Model):
103
106
  blank=True,
104
107
  related_name="default_patients",
105
108
  )
106
- user = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
107
-
108
- created = models.DateTimeField(auto_now_add=True)
109
- modified = models.DateTimeField(auto_now=True)
109
+ user = models.OneToOneField("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
110
110
 
111
111
  @classmethod
112
112
  def find(cls, id: str) -> Patient:
@@ -240,14 +240,12 @@ class PatientAddress(IdentifiableModel):
240
240
  return f"id={self.id}"
241
241
 
242
242
 
243
- class PatientExternalIdentifier(IdentifiableModel):
243
+ class PatientExternalIdentifier(TimestampedModel, IdentifiableModel):
244
244
  """A class representing a patient external identifier."""
245
245
 
246
246
  class Meta:
247
247
  db_table = "canvas_sdk_data_api_patientexternalidentifier_001"
248
248
 
249
- created = models.DateTimeField(auto_now_add=True)
250
- modified = models.DateTimeField(auto_now=True)
251
249
  patient = models.ForeignKey(
252
250
  "v1.Patient",
253
251
  related_name="external_identifiers",
@@ -265,14 +263,12 @@ class PatientExternalIdentifier(IdentifiableModel):
265
263
  return f"id={self.id}"
266
264
 
267
265
 
268
- class PatientSetting(Model):
266
+ class PatientSetting(TimestampedModel):
269
267
  """PatientSetting."""
270
268
 
271
269
  class Meta:
272
270
  db_table = "canvas_sdk_data_api_patientsetting_001"
273
271
 
274
- created = models.DateTimeField(auto_now_add=True)
275
- modified = models.DateTimeField(auto_now=True)
276
272
  patient = models.ForeignKey(
277
273
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="settings", null=True
278
274
  )
@@ -1,20 +1,15 @@
1
1
  from django.db import models
2
2
 
3
- from canvas_sdk.v1.data.base import IdentifiableModel, Model
3
+ from canvas_sdk.v1.data.base import IdentifiableModel
4
+ from canvas_sdk.v1.data.coding import Coding
4
5
 
5
6
 
6
- class PatientConsentRejectionCoding(Model):
7
+ class PatientConsentRejectionCoding(Coding):
7
8
  """Patient Consent Rejection Coding."""
8
9
 
9
10
  class Meta:
10
11
  db_table = "canvas_sdk_data_api_patientconsentrejectioncoding_001"
11
12
 
12
- system = models.CharField(max_length=255)
13
- version = models.CharField(max_length=255)
14
- code = models.CharField(max_length=255)
15
- display = models.CharField(max_length=1000)
16
- user_selected = models.BooleanField()
17
-
18
13
 
19
14
  class PatientConsentExpirationRule(models.TextChoices):
20
15
  """PatientConsentExpirationRule."""
@@ -24,17 +19,12 @@ class PatientConsentExpirationRule(models.TextChoices):
24
19
  END_OF_YEAR = "end_of_year", "End of year"
25
20
 
26
21
 
27
- class PatientConsentCoding(Model):
22
+ class PatientConsentCoding(Coding):
28
23
  """Patient Consent Coding."""
29
24
 
30
25
  class Meta:
31
26
  db_table = "canvas_sdk_data_api_patientconsentcoding_001"
32
27
 
33
- system = models.CharField(max_length=255)
34
- version = models.CharField(max_length=255)
35
- code = models.CharField(max_length=255)
36
- display = models.CharField(max_length=1000)
37
- user_selected = models.BooleanField()
38
28
  expiration_rule = models.CharField(choices=PatientConsentExpirationRule.choices, max_length=255)
39
29
  is_mandatory = models.BooleanField()
40
30
  is_proof_required = models.BooleanField()
@@ -1,6 +1,6 @@
1
1
  from django.db import models
2
2
 
3
- from canvas_sdk.v1.data.base import IdentifiableModel
3
+ from canvas_sdk.v1.data.base import IdentifiableModel, TimestampedModel
4
4
 
5
5
 
6
6
  class PostingMethods(models.TextChoices):
@@ -12,7 +12,7 @@ class PostingMethods(models.TextChoices):
12
12
  OTHER = "other", "Other"
13
13
 
14
14
 
15
- class PaymentCollection(IdentifiableModel):
15
+ class PaymentCollection(TimestampedModel, IdentifiableModel):
16
16
  """Stores the total collected amount and the payment method."""
17
17
 
18
18
  class Meta:
@@ -27,8 +27,5 @@ class PaymentCollection(IdentifiableModel):
27
27
 
28
28
  description = models.TextField()
29
29
 
30
- created = models.DateTimeField(auto_now_add=True)
31
- modified = models.DateTimeField(auto_now=True)
32
-
33
30
 
34
31
  __exports__ = ("PaymentCollection", "PostingMethods")
@@ -3,7 +3,7 @@ from typing import Self
3
3
 
4
4
  from django.db import models
5
5
 
6
- from canvas_sdk.v1.data.base import IdentifiableModel, Model
6
+ from canvas_sdk.v1.data.base import IdentifiableModel, TimestampedModel
7
7
  from canvas_sdk.v1.data.utils import quantize
8
8
 
9
9
 
@@ -15,7 +15,7 @@ class PostingQuerySet(models.QuerySet):
15
15
  return self.filter(entered_in_error__isnull=True)
16
16
 
17
17
 
18
- class BasePosting(Model):
18
+ class BasePosting(TimestampedModel):
19
19
  """
20
20
  Base model to aggregate multiple line item transactions on a claim.
21
21
  """
@@ -40,9 +40,6 @@ class BasePosting(Model):
40
40
  "v1.CanvasUser", on_delete=models.PROTECT, null=True, blank=True
41
41
  )
42
42
 
43
- created = models.DateTimeField(auto_now_add=True)
44
- modified = models.DateTimeField(auto_now=True)
45
-
46
43
  @property
47
44
  def paid_amount(self) -> Decimal:
48
45
  """Returns the total amount paid for this posting."""
@@ -149,7 +146,7 @@ class PatientPosting(BasePosting):
149
146
  return self.discounted_amount + self.paid_amount
150
147
 
151
148
 
152
- class AbstractBulkPosting(IdentifiableModel):
149
+ class AbstractBulkPosting(TimestampedModel, IdentifiableModel):
153
150
  """Patient and Insurance bulk posting shared columns."""
154
151
 
155
152
  class Meta:
@@ -161,9 +158,6 @@ class AbstractBulkPosting(IdentifiableModel):
161
158
 
162
159
  total_paid = models.DecimalField(max_digits=8, decimal_places=2)
163
160
 
164
- created = models.DateTimeField(auto_now_add=True)
165
- modified = models.DateTimeField(auto_now=True)
166
-
167
161
 
168
162
  class BulkPatientPosting(AbstractBulkPosting):
169
163
  """Model to aggregate bulk patient payments on multiple claims."""
@@ -1,7 +1,15 @@
1
1
  from django.db import models
2
2
 
3
- from canvas_sdk.v1.data.base import IdentifiableModel, Model
4
- from canvas_sdk.v1.data.common import TaxIDType
3
+ from canvas_sdk.v1.data.base import IdentifiableModel, Model, TimestampedModel
4
+ from canvas_sdk.v1.data.common import (
5
+ AddressState,
6
+ AddressType,
7
+ AddressUse,
8
+ ContactPointState,
9
+ ContactPointSystem,
10
+ ContactPointUse,
11
+ TaxIDType,
12
+ )
5
13
 
6
14
 
7
15
  class PracticeLocationPOS(models.TextChoices):
@@ -53,14 +61,12 @@ class PracticeLocationPOS(models.TextChoices):
53
61
  OTHER = "99", "Other Place of Service"
54
62
 
55
63
 
56
- class PracticeLocation(IdentifiableModel):
64
+ class PracticeLocation(TimestampedModel, IdentifiableModel):
57
65
  """PracticeLocation."""
58
66
 
59
67
  class Meta:
60
68
  db_table = "canvas_sdk_data_api_practicelocation_001"
61
69
 
62
- created = models.DateTimeField(auto_now_add=True)
63
- modified = models.DateTimeField(auto_now=True)
64
70
  organization = models.ForeignKey(
65
71
  "v1.Organization", on_delete=models.DO_NOTHING, related_name="practice_locations", null=True
66
72
  )
@@ -69,7 +75,7 @@ class PracticeLocation(IdentifiableModel):
69
75
  short_name = models.CharField(max_length=255)
70
76
  background_image_url = models.CharField(max_length=255)
71
77
  background_gradient = models.CharField(max_length=255)
72
- active = models.BooleanField()
78
+ active = models.BooleanField(default=True)
73
79
  npi_number = models.CharField(max_length=10)
74
80
  bill_through_organization = models.BooleanField()
75
81
  tax_id = models.CharField(max_length=25)
@@ -77,12 +83,42 @@ class PracticeLocation(IdentifiableModel):
77
83
  billing_location_name = models.CharField(max_length=255)
78
84
  group_npi_number = models.CharField(max_length=10)
79
85
  taxonomy_number = models.CharField(max_length=10)
80
- include_zz_qualifier = models.BooleanField()
86
+ include_zz_qualifier = models.BooleanField(default=False)
81
87
 
82
88
  def __str__(self) -> str:
83
89
  return self.full_name
84
90
 
85
91
 
92
+ class PracticeLocationAddress(Model):
93
+ """PracticeLocationAddress."""
94
+
95
+ class Meta:
96
+ db_table = "canvas_sdk_data_api_practicelocationaddress_001"
97
+
98
+ practice_location = models.ForeignKey(
99
+ "v1.PracticeLocation", on_delete=models.DO_NOTHING, related_name="addresses", null=True
100
+ )
101
+ line1 = models.CharField(max_length=255, default="", blank=True)
102
+ line2 = models.CharField(max_length=255, default="", blank=True)
103
+ city = models.CharField(max_length=255)
104
+ district = models.CharField(max_length=255, blank=True, default="")
105
+ state_code = models.CharField(max_length=2)
106
+ postal_code = models.CharField(max_length=255)
107
+ use = models.CharField(choices=AddressUse.choices, max_length=10, default=AddressUse.WORK)
108
+ type = models.CharField(choices=AddressType.choices, max_length=10, default=AddressType.BOTH)
109
+ longitude = models.FloatField(null=True, blank=True)
110
+ latitude = models.FloatField(null=True, blank=True)
111
+ start = models.DateField(null=True, blank=True)
112
+ end = models.DateField(null=True, blank=True)
113
+ country = models.CharField(max_length=255)
114
+ state = models.CharField(
115
+ choices=AddressState.choices, max_length=20, default=AddressState.ACTIVE
116
+ )
117
+
118
+ def __str__(self) -> str:
119
+ return f"Address for {self.practice_location}"
120
+
121
+
86
122
  class PracticeLocationSetting(Model):
87
123
  """PracticeLocationSetting."""
88
124
 
@@ -99,8 +135,31 @@ class PracticeLocationSetting(Model):
99
135
  return self.name
100
136
 
101
137
 
138
+ class PracticeLocationContactPoint(IdentifiableModel):
139
+ """PracticeLocationContactPoint."""
140
+
141
+ class Meta:
142
+ db_table = "canvas_sdk_data_api_practicelocationcontactpoint_001"
143
+
144
+ practice_location = models.ForeignKey(
145
+ "v1.PracticeLocation", on_delete=models.PROTECT, related_name="telecom"
146
+ )
147
+ system = models.CharField(choices=ContactPointSystem.choices, max_length=20, db_index=True)
148
+ value = models.CharField(max_length=100, db_index=True)
149
+ use = models.CharField(
150
+ choices=ContactPointUse.choices, max_length=20, default=ContactPointUse.HOME
151
+ )
152
+ use_notes = models.CharField(max_length=255, blank=True, default="")
153
+ rank = models.IntegerField(default=1)
154
+ state = models.CharField(
155
+ choices=ContactPointState.choices, max_length=20, default=ContactPointState.ACTIVE
156
+ )
157
+
158
+
102
159
  __exports__ = (
103
160
  "PracticeLocationPOS",
104
161
  "PracticeLocation",
162
+ "PracticeLocationContactPoint",
105
163
  "PracticeLocationSetting",
164
+ "PracticeLocationAddress",
106
165
  )
@@ -8,6 +8,7 @@ from canvas_sdk.v1.data.base import (
8
8
  CommittableQuerySetMixin,
9
9
  ForPatientQuerySetMixin,
10
10
  IdentifiableModel,
11
+ TimestampedModel,
11
12
  )
12
13
 
13
14
 
@@ -26,7 +27,7 @@ class Status(models.TextChoices):
26
27
  INACTIVE = "inactive", "inactive"
27
28
 
28
29
 
29
- class ProtocolOverrideQuerySet(BaseQuerySet, ForPatientQuerySetMixin, CommittableQuerySetMixin):
30
+ class ProtocolOverrideQuerySet(ForPatientQuerySetMixin, CommittableQuerySetMixin, BaseQuerySet):
30
31
  """ProtocolOverrideQuerySet."""
31
32
 
32
33
  pass
@@ -35,7 +36,7 @@ class ProtocolOverrideQuerySet(BaseQuerySet, ForPatientQuerySetMixin, Committabl
35
36
  ProtocolOverrideManager = BaseModelManager.from_queryset(ProtocolOverrideQuerySet)
36
37
 
37
38
 
38
- class ProtocolOverride(IdentifiableModel):
39
+ class ProtocolOverride(TimestampedModel, IdentifiableModel):
39
40
  """ProtocolOverride."""
40
41
 
41
42
  class Meta:
@@ -43,8 +44,6 @@ class ProtocolOverride(IdentifiableModel):
43
44
 
44
45
  objects = cast(ProtocolOverrideQuerySet, ProtocolOverrideManager())
45
46
 
46
- created = models.DateTimeField(auto_now_add=True)
47
- modified = models.DateTimeField(auto_now=True)
48
47
  deleted = models.BooleanField()
49
48
  committer = models.ForeignKey(
50
49
  "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
@@ -1,6 +1,8 @@
1
1
  from django.contrib.postgres.fields import ArrayField
2
2
  from django.db import models
3
3
 
4
+ from canvas_sdk.v1.data.base import TimestampedModel
5
+
4
6
 
5
7
  class ProtocolResultStatus(models.TextChoices):
6
8
  """Constants for ProtocolResultStatus."""
@@ -12,7 +14,7 @@ class ProtocolResultStatus(models.TextChoices):
12
14
  STATUS_NOT_RELEVANT = "not_relevant"
13
15
 
14
16
 
15
- class ProtocolResult(models.Model):
17
+ class ProtocolResult(TimestampedModel):
16
18
  """ProtocolResult."""
17
19
 
18
20
  class Meta:
@@ -36,8 +38,6 @@ class ProtocolResult(models.Model):
36
38
  next_review = models.DateTimeField(null=True)
37
39
  feedback_enabled = models.BooleanField(default=False)
38
40
  plugin_can_be_snoozed = models.BooleanField(default=False)
39
- created = models.DateTimeField(auto_now_add=True)
40
- modified = models.DateTimeField(auto_now=True)
41
41
 
42
42
 
43
43
  __exports__ = (