canvas 0.41.0__py3-none-any.whl → 0.43.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 (40) hide show
  1. {canvas-0.41.0.dist-info → canvas-0.43.0.dist-info}/METADATA +1 -1
  2. {canvas-0.41.0.dist-info → canvas-0.43.0.dist-info}/RECORD +40 -28
  3. canvas_generated/messages/effects_pb2.py +2 -2
  4. canvas_generated/messages/effects_pb2.pyi +4 -0
  5. canvas_sdk/effects/patient/__init__.py +10 -2
  6. canvas_sdk/effects/patient/base.py +20 -1
  7. canvas_sdk/effects/patient/create_patient_external_identifier.py +40 -0
  8. canvas_sdk/effects/patient_metadata/__init__.py +13 -0
  9. canvas_sdk/effects/patient_metadata/base.py +48 -0
  10. canvas_sdk/effects/protocol_card/__init__.py +4 -1
  11. canvas_sdk/effects/protocol_card/protocol_card.py +2 -0
  12. canvas_sdk/utils/http.py +46 -2
  13. canvas_sdk/v1/data/__init__.py +29 -0
  14. canvas_sdk/v1/data/allergy_intolerance.py +6 -2
  15. canvas_sdk/v1/data/assessment.py +7 -3
  16. canvas_sdk/v1/data/billing.py +1 -1
  17. canvas_sdk/v1/data/claim.py +321 -0
  18. canvas_sdk/v1/data/claim_line_item.py +140 -0
  19. canvas_sdk/v1/data/command.py +12 -3
  20. canvas_sdk/v1/data/condition.py +7 -2
  21. canvas_sdk/v1/data/detected_issue.py +9 -3
  22. canvas_sdk/v1/data/device.py +9 -3
  23. canvas_sdk/v1/data/discount.py +21 -0
  24. canvas_sdk/v1/data/fields.py +37 -0
  25. canvas_sdk/v1/data/imaging.py +18 -6
  26. canvas_sdk/v1/data/invoice.py +62 -0
  27. canvas_sdk/v1/data/lab.py +36 -12
  28. canvas_sdk/v1/data/line_item_transaction.py +83 -0
  29. canvas_sdk/v1/data/medication.py +6 -2
  30. canvas_sdk/v1/data/observation.py +9 -3
  31. canvas_sdk/v1/data/organization.py +3 -1
  32. canvas_sdk/v1/data/payment_collection.py +35 -0
  33. canvas_sdk/v1/data/posting.py +225 -0
  34. canvas_sdk/v1/data/protocol_override.py +6 -2
  35. canvas_sdk/v1/data/questionnaire.py +6 -2
  36. canvas_sdk/v1/data/utils.py +10 -0
  37. protobufs/canvas_generated/messages/effects.proto +2 -0
  38. {canvas-0.41.0.dist-info → canvas-0.43.0.dist-info}/WHEEL +0 -0
  39. {canvas-0.41.0.dist-info → canvas-0.43.0.dist-info}/entry_points.txt +0 -0
  40. /canvas_sdk/effects/{patient_metadata_create_form.py → patient_metadata/patient_metadata_create_form.py} +0 -0
@@ -0,0 +1,321 @@
1
+ from decimal import Decimal
2
+ from typing import TYPE_CHECKING, Self
3
+
4
+ from django.db import models
5
+
6
+ from canvas_sdk.v1.data.common import PersonSex
7
+ from canvas_sdk.v1.data.coverage import CoverageRelationshipCode, CoverageType
8
+ from canvas_sdk.v1.data.fields import ChoiceArrayField
9
+ from canvas_sdk.v1.data.utils import quantize
10
+
11
+ if TYPE_CHECKING:
12
+ from canvas_sdk.v1.data.claim_line_item import ClaimLineItemQuerySet
13
+
14
+
15
+ class InstallmentPlanStatus(models.TextChoices):
16
+ """InstallmentPlanStatus."""
17
+
18
+ ACTIVE = "active", "Active"
19
+ COMPLETED = "completed", "Completed"
20
+ CANCELLED = "cancelled", "Cancelled"
21
+
22
+
23
+ class InstallmentPlan(models.Model):
24
+ """InstallmentPlan."""
25
+
26
+ class Meta:
27
+ managed = False
28
+ db_table = "canvas_sdk_data_api_installmentplan_001"
29
+
30
+ creator = models.ForeignKey("v1.CanvasUser", on_delete=models.CASCADE)
31
+ patient = models.ForeignKey(
32
+ "v1.Patient", on_delete=models.CASCADE, related_name="installment_plans"
33
+ )
34
+ total_amount = models.DecimalField(max_digits=8, decimal_places=2)
35
+ status = models.CharField(choices=InstallmentPlanStatus.choices)
36
+ expected_payoff_date = models.DateField()
37
+ created_at = models.DateTimeField()
38
+ updated_at = models.DateTimeField()
39
+
40
+
41
+ class ClaimQueueColumns(models.TextChoices):
42
+ """ClaimQueueColumns."""
43
+
44
+ NOTE_TYPE = "NoteType", "Note type"
45
+ CLAIM_ID = "ClaimID", "Claim ID"
46
+ DOS = "DateOfService", "Date of service"
47
+ PATIENT = "Patient", "Patient"
48
+ ACTIVE_INSURANCE = "ActiveInsurance", "Active insurance"
49
+ INSURANCE_BALANCE = "InsuranceBalance", "Insurance balance"
50
+ PATIENT_BALANCE = "PatientBalance", "Patient balance"
51
+ DAYS_IN_QUEUE = "DaysInQueue", "Days in queue"
52
+ PROVIDER = "Provider", "Provider"
53
+ GUARANTOR = "Guarantor", "Guarantor"
54
+ LATEST_REMIT = "LatestRemit", "Latest remit"
55
+ LAST_INVOICED = "LastInvoiced", "Last invoiced"
56
+ SNOOZED_UNTIL = "SnoozedUntil", "Snoozed until"
57
+ LABELS = "Labels", "Labels"
58
+
59
+
60
+ class ClaimQueues(models.IntegerChoices):
61
+ """ClaimQueues."""
62
+
63
+ APPOINTMENT = 1, "Appointment"
64
+ NEEDS_CLINICIAN_REVIEW = 2, "NeedsClinicianReview"
65
+ NEEDS_CODING_REVIEW = 3, "NeedsCodingReview"
66
+ QUEUED_FOR_SUBMISSION = 4, "QueuedForSubmission"
67
+ FILED_AWAITING_RESPONSE = 5, "FiledAwaitingResponse"
68
+ REJECTED_NEEDS_REVIEW = 6, "RejectedNeedsReview"
69
+ ADJUDICATED_OPEN_BALANCE = 7, "AdjudicatedOpenBalance"
70
+ PATIENT_BALANCE = 8, "PatientBalance"
71
+ ZERO_BALANCE = 9, "ZeroBalance"
72
+ TRASH = 10, "Trash"
73
+
74
+
75
+ class ClaimQueue(models.Model):
76
+ """ClaimQueue."""
77
+
78
+ class Meta:
79
+ managed = False
80
+ db_table = "canvas_sdk_data_quality_and_revenue_queue_001"
81
+
82
+ dbid = models.BigIntegerField(primary_key=True)
83
+ queue_sort_ordering = models.IntegerField()
84
+ name = models.CharField()
85
+ display_name = models.CharField()
86
+ description = models.CharField()
87
+ show_in_revenue = models.BooleanField()
88
+ visible_columns = ChoiceArrayField(models.CharField(choices=ClaimQueueColumns.choices))
89
+
90
+ created = models.DateTimeField()
91
+ modified = models.DateTimeField()
92
+
93
+
94
+ class ClaimPayerOrder(models.TextChoices):
95
+ """ClaimPayerOrder."""
96
+
97
+ PRIMARY = "Primary", "Primary"
98
+ SECONDARY = "Secondary", "Secondary"
99
+ TERTIARY = "Tertiary", "Tertiary"
100
+ QUATERNARY = "Quaternary", "Quaternary"
101
+ QUINARY = "Quinary", "Quinary"
102
+
103
+
104
+ class ClaimTypeCode(models.TextChoices):
105
+ """ClaimTypeCode."""
106
+
107
+ WORKING_AGED = "12", "Working Aged (Age 65 or older)"
108
+ ESRD = "13", "End-Stage Renal Disease"
109
+ NO_FAULT = "14", "No-fault"
110
+ WORKERS_COMP = "15", "Workers Compensation"
111
+ BLACK_LUNG = "41", "Black Lung"
112
+ VA = "42", "Veterans Administration"
113
+ DISABLED = "43", "Disabled (Under Age 65)"
114
+ OTHER_LIABILITY = "47", "Other Liability Insurance is primary"
115
+ UNNECESSARY = "", "No Typecode necessary"
116
+
117
+
118
+ class ClaimCoverageQuerySet(models.QuerySet):
119
+ """ClaimCoverageQuerySet."""
120
+
121
+ def active(self) -> Self:
122
+ """Filter active claim coverages."""
123
+ return self.filter(active=True)
124
+
125
+
126
+ class ClaimCoverage(models.Model):
127
+ """A model that represents the link between a claim and a specific insurance coverage."""
128
+
129
+ class Meta:
130
+ managed = False
131
+ db_table = "canvas_sdk_data_quality_and_revenue_claimcoverage_001"
132
+
133
+ objects = ClaimCoverageQuerySet.as_manager()
134
+
135
+ dbid = models.BigIntegerField(primary_key=True)
136
+
137
+ claim = models.ForeignKey("Claim", on_delete=models.CASCADE, related_name="coverages")
138
+
139
+ coverage = models.ForeignKey(
140
+ "v1.Coverage", related_name="claim_coverages", on_delete=models.PROTECT
141
+ )
142
+
143
+ active = models.BooleanField()
144
+ payer_name = models.CharField()
145
+ payer_id = models.CharField()
146
+ payer_typecode = models.CharField()
147
+ payer_order = models.CharField(choices=ClaimPayerOrder.choices)
148
+ payer_addr1 = models.CharField()
149
+ payer_addr2 = models.CharField()
150
+ payer_city = models.CharField()
151
+ payer_state = models.CharField()
152
+ payer_zip = models.CharField()
153
+ payer_plan_type = models.CharField(choices=ClaimTypeCode.choices)
154
+ coverage_type = models.CharField(choices=CoverageType.choices)
155
+
156
+ subscriber_employer = models.CharField()
157
+ subscriber_group = models.CharField()
158
+ subscriber_number = models.CharField()
159
+ subscriber_plan = models.CharField()
160
+ subscriber_dob = models.CharField()
161
+ subscriber_first_name = models.CharField()
162
+ subscriber_last_name = models.CharField()
163
+ subscriber_middle_name = models.CharField()
164
+ subscriber_phone = models.CharField()
165
+ subscriber_sex = models.CharField(choices=PersonSex.choices)
166
+ subscriber_addr1 = models.CharField()
167
+ subscriber_addr2 = models.CharField()
168
+ subscriber_city = models.CharField()
169
+ subscriber_state = models.CharField()
170
+ subscriber_zip = models.CharField()
171
+ subscriber_country = models.CharField()
172
+ patient_relationship_to_subscriber = models.CharField(choices=CoverageRelationshipCode.choices)
173
+
174
+ pay_to_addr1 = models.CharField()
175
+ pay_to_addr2 = models.CharField()
176
+ pay_to_city = models.CharField()
177
+ pay_to_state = models.CharField()
178
+ pay_to_zip = models.CharField()
179
+
180
+ resubmission_code = models.CharField()
181
+ payer_icn = models.CharField()
182
+
183
+ created = models.DateTimeField()
184
+ modified = models.DateTimeField()
185
+
186
+
187
+ class ClaimPatient(models.Model):
188
+ """ClaimPatient."""
189
+
190
+ class Meta:
191
+ managed = False
192
+ db_table = "canvas_sdk_data_quality_and_revenue_claimpatient_001"
193
+
194
+ dbid = models.BigIntegerField(primary_key=True)
195
+ claim = models.OneToOneField("v1.Claim", on_delete=models.CASCADE, related_name="patient")
196
+ photo = models.CharField()
197
+ dob = models.CharField()
198
+ first_name = models.CharField()
199
+ last_name = models.CharField()
200
+ middle_name = models.CharField()
201
+ phone = models.CharField()
202
+ sex = models.CharField(choices=PersonSex.choices)
203
+ ssn = models.CharField()
204
+ addr1 = models.CharField()
205
+ addr2 = models.CharField()
206
+ city = models.CharField()
207
+ state = models.CharField()
208
+ zip = models.CharField()
209
+ country = models.CharField()
210
+
211
+ created = models.DateTimeField()
212
+ modified = models.DateTimeField()
213
+
214
+
215
+ class ClaimQueryset(models.QuerySet):
216
+ """ClaimQueryset."""
217
+
218
+ def active(self) -> Self:
219
+ """Active claims."""
220
+ return self.exclude(current_queue__queue_sort_ordering=ClaimQueues.TRASH)
221
+
222
+
223
+ class Claim(models.Model):
224
+ """Claim."""
225
+
226
+ class Meta:
227
+ managed = False
228
+ db_table = "canvas_sdk_data_quality_and_revenue_claim_001"
229
+
230
+ objects = ClaimQueryset.as_manager()
231
+
232
+ id = models.UUIDField()
233
+ dbid = models.BigIntegerField(primary_key=True)
234
+ note = models.ForeignKey("v1.Note", on_delete=models.PROTECT, related_name="claims", null=True)
235
+ installment_plan = models.ForeignKey(
236
+ InstallmentPlan, on_delete=models.SET_NULL, related_name="claims", null=True
237
+ )
238
+ current_queue = models.ForeignKey(ClaimQueue, on_delete=models.PROTECT, related_name="claims")
239
+ latest_invoice = models.ForeignKey("v1.Invoice", on_delete=models.SET_NULL, null=True)
240
+ current_coverage = models.ForeignKey(
241
+ ClaimCoverage, related_name="claims", on_delete=models.SET_NULL, null=True
242
+ )
243
+
244
+ accept_assign = models.BooleanField()
245
+ auto_accident = models.BooleanField()
246
+ auto_accident_state = models.CharField()
247
+ employment_related = models.BooleanField()
248
+ other_accident = models.BooleanField()
249
+ accident_code = models.CharField()
250
+ illness_date = models.DateField()
251
+ remote_batch_id = models.CharField()
252
+ remote_file_id = models.CharField()
253
+ prior_auth = models.CharField()
254
+
255
+ narrative = models.CharField()
256
+ account_number = models.CharField()
257
+ snoozed_until = models.DateField()
258
+
259
+ patient_balance = models.DecimalField(max_digits=8, decimal_places=2)
260
+ aggregate_coverage_balance = models.DecimalField(max_digits=8, decimal_places=2)
261
+ created = models.DateTimeField()
262
+ modified = models.DateTimeField()
263
+
264
+ @property
265
+ def total_charges(self) -> Decimal:
266
+ """Total charges for the claim."""
267
+ line_items = self.get_active_claim_line_items()
268
+ if line_items:
269
+ return quantize(sum(line_item.charge for line_item in line_items))
270
+ return Decimal("0.00")
271
+
272
+ @property
273
+ def total_paid(self) -> Decimal | int:
274
+ """Total paid amount for the claim."""
275
+ return sum(posting.paid_amount for posting in self.postings.active()) or Decimal("0.00")
276
+
277
+ @property
278
+ def total_adjusted(self) -> Decimal | int:
279
+ """Total adjusted amount for the claim."""
280
+ return sum(
281
+ posting.adjusted_and_transferred_amount for posting in self.postings.active()
282
+ ) or Decimal("0.00")
283
+
284
+ @property
285
+ def balance(self) -> Decimal:
286
+ """Balance for the claim."""
287
+ return self.aggregate_coverage_balance + self.patient_balance
288
+
289
+ @property
290
+ def total_patient_paid(self) -> Decimal | int:
291
+ """Total amount paid by the patient."""
292
+ return sum(posting.paid_amount for posting in self.patient.postings.active()) or Decimal(
293
+ "0.00"
294
+ )
295
+
296
+ @property
297
+ def total_payer_paid(self) -> Decimal | int:
298
+ """Total amount paid by the coverages."""
299
+ return sum(
300
+ posting.paid_amount
301
+ for coverage in self.coverages.active()
302
+ for posting in coverage.postings.active()
303
+ ) or Decimal("0.00")
304
+
305
+ def get_active_claim_line_items(self) -> "ClaimLineItemQuerySet":
306
+ """Return the active claim line items."""
307
+ return self.line_items.active().exclude_copay_and_unlinked()
308
+
309
+
310
+ __exports__ = (
311
+ "Claim",
312
+ "ClaimQueue",
313
+ "ClaimCoverage",
314
+ "ClaimPatient",
315
+ "ClaimPayerOrder",
316
+ "ClaimQueues",
317
+ "ClaimQueueColumns",
318
+ "ClaimTypeCode",
319
+ "InstallmentPlan",
320
+ "InstallmentPlanStatus",
321
+ )
@@ -0,0 +1,140 @@
1
+ from decimal import Decimal
2
+ from typing import Any, Self
3
+
4
+ from django.db import models
5
+ from django.db.models import Q, Sum
6
+ from django.db.models.functions import Coalesce
7
+
8
+ from canvas_sdk.v1.data.note import PracticeLocationPOS
9
+
10
+
11
+ class ClaimLineItemStatus(models.TextChoices):
12
+ """ClaimLineItemStatus."""
13
+
14
+ ACTIVE = "active", "Active"
15
+ REMOVED = "removed", "Removed"
16
+
17
+
18
+ class LineItemCodes(models.TextChoices):
19
+ """LineItemCodes."""
20
+
21
+ COPAY = "COPAY"
22
+ UNLINKED = "UNLINKED"
23
+
24
+
25
+ class FamilyPlanningOptions(models.TextChoices):
26
+ """FamilyPlanningOptions."""
27
+
28
+ YES = ("Y", "Yes")
29
+ NO = ("N", "No")
30
+
31
+
32
+ class ClaimLineItemQuerySet(models.QuerySet):
33
+ """ClaimLineItemQuerySet."""
34
+
35
+ def filter(self, *args: Any, **kwargs: Any) -> Self:
36
+ """Apply standard filtering to the QuerySet."""
37
+ return super().filter(*args, **kwargs)
38
+
39
+ def exclude(self, *args: Any, **kwargs: Any) -> Self:
40
+ """Apply standard exclusion to the QuerySet."""
41
+ return super().exclude(*args, **kwargs)
42
+
43
+ def apply_ordering(self) -> Self:
44
+ """Apply ordering to the QuerySet."""
45
+ return self.order_by("from_date", "-proc_code")
46
+
47
+ def active(self) -> Self:
48
+ """Return only active claim line items."""
49
+ return self.exclude(status=ClaimLineItemStatus.REMOVED).apply_ordering()
50
+
51
+ def exclude_removed_line_item_without_active_posting(self) -> Self:
52
+ """Exclude out any line items that are deleted without any active postings."""
53
+ return (
54
+ self.filter(
55
+ Q(status=ClaimLineItemStatus.ACTIVE)
56
+ | Q(
57
+ newlineitempayments__isnull=False,
58
+ newlineitempayments__entered_in_error__isnull=True,
59
+ )
60
+ | Q(
61
+ newlineitemadjustments__isnull=False,
62
+ newlineitemadjustments__entered_in_error__isnull=True,
63
+ )
64
+ | Q(
65
+ lineitemtransfers__isnull=False,
66
+ lineitemtransfers__entered_in_error__isnull=True,
67
+ )
68
+ )
69
+ .exclude_removed_line_items_without_balances()
70
+ .apply_ordering()
71
+ .distinct()
72
+ )
73
+
74
+ def exclude_removed_line_items_without_balances(self) -> Self:
75
+ """Exclude removed line items with zero balances."""
76
+ return (
77
+ self.annotate(
78
+ sum_of_all_payments=Coalesce(Sum("newlineitempayments__amount"), Decimal(0)),
79
+ sum_of_all_adjustments=Coalesce(Sum("newlineitemadjustments__amount"), Decimal(0)),
80
+ sum_of_all_transfers=Coalesce(Sum("lineitemtransfers__amount"), Decimal(0)),
81
+ )
82
+ .exclude(
83
+ Q(
84
+ status=ClaimLineItemStatus.REMOVED,
85
+ sum_of_all_payments=0,
86
+ sum_of_all_adjustments=0,
87
+ sum_of_all_transfers=0,
88
+ )
89
+ )
90
+ .distinct()
91
+ )
92
+
93
+ def exclude_copay_and_unlinked(self) -> Self:
94
+ """Exclude both co-pay and unlinked line items."""
95
+ return self.exclude(
96
+ proc_code__in=[LineItemCodes.UNLINKED.value, LineItemCodes.COPAY.value]
97
+ ).apply_ordering()
98
+
99
+ def exclude_copay(self) -> Self:
100
+ """Exclude only co-pay line items."""
101
+ return self.exclude(proc_code=LineItemCodes.COPAY.value).apply_ordering()
102
+
103
+ def exclude_unlinked(self) -> Self:
104
+ """Exclude only unlinked line items."""
105
+ return self.exclude(proc_code=LineItemCodes.UNLINKED.value).apply_ordering()
106
+
107
+
108
+ class ClaimLineItem(models.Model):
109
+ """ClaimLineItem."""
110
+
111
+ class Meta:
112
+ managed = False
113
+ db_table = "canvas_sdk_data_quality_and_revenue_claimlineitem_001"
114
+
115
+ objects = ClaimLineItemQuerySet.as_manager()
116
+
117
+ dbid = models.BigIntegerField(primary_key=True)
118
+ billing_line_item = models.ForeignKey("v1.BillingLineItem", on_delete=models.CASCADE, null=True)
119
+ claim = models.ForeignKey("v1.Claim", on_delete=models.CASCADE, related_name="line_items")
120
+ status = models.CharField(choices=ClaimLineItemStatus.choices)
121
+ charge = models.DecimalField(max_digits=8, decimal_places=2)
122
+ from_date = models.CharField()
123
+ thru_date = models.CharField()
124
+ narrative = models.CharField()
125
+ ndc_code = models.CharField()
126
+ ndc_dosage = models.CharField()
127
+ ndc_measure = models.CharField()
128
+ place_of_service = models.CharField(choices=PracticeLocationPOS.choices)
129
+ proc_code = models.CharField()
130
+ display = models.CharField()
131
+ remote_chg_id = models.CharField()
132
+ units = models.IntegerField()
133
+ epsdt = models.CharField()
134
+ family_planning = models.CharField(choices=FamilyPlanningOptions.choices)
135
+
136
+ created = models.DateTimeField()
137
+ modified = models.DateTimeField()
138
+
139
+
140
+ __exports__ = ("ClaimLineItem", "ClaimLineItemStatus", "LineItemCodes", "FamilyPlanningOptions")
@@ -13,9 +13,18 @@ class Command(models.Model):
13
13
  dbid = models.BigIntegerField(primary_key=True)
14
14
  created = models.DateTimeField()
15
15
  modified = models.DateTimeField()
16
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
17
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
18
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
16
+ originator = models.ForeignKey(
17
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="commands_originated"
18
+ )
19
+ committer = models.ForeignKey(
20
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="commands_committed"
21
+ )
22
+ entered_in_error = models.ForeignKey(
23
+ "v1.CanvasUser",
24
+ on_delete=models.DO_NOTHING,
25
+ null=True,
26
+ related_name="commands_entered_in_error",
27
+ )
19
28
  state = models.CharField()
20
29
  patient = models.ForeignKey("v1.Patient", on_delete=models.DO_NOTHING, null=True)
21
30
  note = models.ForeignKey("v1.Note", on_delete=models.DO_NOTHING, related_name="commands")
@@ -50,14 +50,19 @@ class Condition(models.Model):
50
50
  id = models.UUIDField()
51
51
  dbid = models.BigIntegerField(primary_key=True)
52
52
  deleted = models.BooleanField()
53
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
54
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
53
+ entered_in_error = models.ForeignKey(
54
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
55
+ )
56
+ committer = models.ForeignKey(
57
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
58
+ )
55
59
  patient = models.ForeignKey(
56
60
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="conditions", null=True
57
61
  )
58
62
  onset_date = models.DateField()
59
63
  resolution_date = models.DateField()
60
64
  clinical_status = models.CharField(choices=ClinicalStatus.choices)
65
+ surgical = models.BooleanField()
61
66
 
62
67
 
63
68
  class ConditionCoding(models.Model):
@@ -14,9 +14,15 @@ class DetectedIssue(models.Model):
14
14
  modified = models.DateTimeField()
15
15
  identified = models.DateTimeField()
16
16
  deleted = models.BooleanField()
17
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
18
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
19
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
17
+ originator = models.ForeignKey(
18
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
19
+ )
20
+ committer = models.ForeignKey(
21
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
22
+ )
23
+ entered_in_error = models.ForeignKey(
24
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
25
+ )
20
26
  patient = models.ForeignKey(
21
27
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="detected_issues", null=True
22
28
  )
@@ -12,9 +12,15 @@ class Device(models.Model):
12
12
  dbid = models.BigIntegerField(primary_key=True)
13
13
  created = models.DateTimeField()
14
14
  modified = models.DateTimeField()
15
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
16
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
17
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
15
+ originator = models.ForeignKey(
16
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
17
+ )
18
+ committer = models.ForeignKey(
19
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
20
+ )
21
+ entered_in_error = models.ForeignKey(
22
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
23
+ )
18
24
  patient = models.ForeignKey(
19
25
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="devices", null=True
20
26
  )
@@ -0,0 +1,21 @@
1
+ from django.db import models
2
+
3
+
4
+ class Discount(models.Model):
5
+ """Model to represent a discount applied to a claim or patient posting."""
6
+
7
+ class Meta:
8
+ managed = False
9
+ db_table = "canvas_sdk_data_quality_and_revenue_discount_001"
10
+
11
+ dbid = models.BigIntegerField(primary_key=True)
12
+ name = models.CharField()
13
+ adjustment_group = models.CharField()
14
+ adjustment_code = models.CharField()
15
+ discount = models.DecimalField(max_digits=8, decimal_places=2)
16
+
17
+ created = models.DateTimeField()
18
+ modified = models.DateTimeField()
19
+
20
+
21
+ __exports__ = ("Discount",)
@@ -0,0 +1,37 @@
1
+ from typing import Any, cast
2
+
3
+ from django import forms
4
+ from django.contrib.postgres.fields import ArrayField
5
+ from django.forms import SelectMultiple
6
+
7
+
8
+ class ArraySelectMultiple(SelectMultiple):
9
+ """ArraySelectMultiple."""
10
+
11
+ def value_omitted_from_data(self, data: Any, files: Any, name: str) -> bool:
12
+ """Override to check if the value is omitted from data."""
13
+ return False
14
+
15
+
16
+ class ChoiceArrayField(ArrayField):
17
+ """ChoiceArrayField."""
18
+
19
+ def formfield(
20
+ self,
21
+ form_class: type[forms.Field] | None = None,
22
+ choices_form_class: type[forms.ChoiceField] | None = None,
23
+ **kwargs: Any,
24
+ ) -> forms.Field:
25
+ """Override formfield to use a custom widget."""
26
+ defaults = {
27
+ "form_class": forms.TypedMultipleChoiceField,
28
+ "choices": self.base_field.choices,
29
+ "coerce": self.base_field.to_python,
30
+ "widget": ArraySelectMultiple,
31
+ }
32
+ defaults.update(kwargs)
33
+
34
+ return cast(forms.Field, super(ArrayField, self).formfield(**defaults)) # type: ignore[arg-type]
35
+
36
+
37
+ __exports__ = ()
@@ -19,10 +19,16 @@ class ImagingOrder(models.Model):
19
19
  dbid = models.BigIntegerField(primary_key=True)
20
20
  created = models.DateTimeField()
21
21
  modified = models.DateTimeField()
22
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
22
+ originator = models.ForeignKey(
23
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
24
+ )
23
25
  deleted = models.BooleanField()
24
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
25
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING)
26
+ committer = models.ForeignKey(
27
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
28
+ )
29
+ entered_in_error = models.ForeignKey(
30
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, related_name="+"
31
+ )
26
32
  patient = models.ForeignKey(
27
33
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="imaging_orders", null=True
28
34
  )
@@ -52,10 +58,16 @@ class ImagingReview(models.Model):
52
58
  dbid = models.BigIntegerField(primary_key=True)
53
59
  created = models.DateTimeField()
54
60
  modified = models.DateTimeField()
55
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
61
+ originator = models.ForeignKey(
62
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
63
+ )
56
64
  deleted = models.BooleanField()
57
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
58
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
65
+ committer = models.ForeignKey(
66
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
67
+ )
68
+ entered_in_error = models.ForeignKey(
69
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
70
+ )
59
71
  patient_communication_method = models.CharField(choices=ReviewPatientCommunicationMethod)
60
72
  # TODO - uncomment when Note model is complete
61
73
  # note = models.ForeignKey('v1.Note', on_delete=models.DO_NOTHING, related_name="imaging_reviews", null=True)