canvas 0.42.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 (37) hide show
  1. {canvas-0.42.0.dist-info → canvas-0.43.0.dist-info}/METADATA +1 -1
  2. {canvas-0.42.0.dist-info → canvas-0.43.0.dist-info}/RECORD +37 -27
  3. canvas_generated/messages/effects_pb2.py +2 -2
  4. canvas_generated/messages/effects_pb2.pyi +2 -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/protocol_card/__init__.py +4 -1
  9. canvas_sdk/effects/protocol_card/protocol_card.py +2 -0
  10. canvas_sdk/utils/http.py +46 -2
  11. canvas_sdk/v1/data/__init__.py +29 -0
  12. canvas_sdk/v1/data/allergy_intolerance.py +6 -2
  13. canvas_sdk/v1/data/assessment.py +7 -3
  14. canvas_sdk/v1/data/billing.py +1 -1
  15. canvas_sdk/v1/data/claim.py +321 -0
  16. canvas_sdk/v1/data/claim_line_item.py +140 -0
  17. canvas_sdk/v1/data/command.py +12 -3
  18. canvas_sdk/v1/data/condition.py +7 -2
  19. canvas_sdk/v1/data/detected_issue.py +9 -3
  20. canvas_sdk/v1/data/device.py +9 -3
  21. canvas_sdk/v1/data/discount.py +21 -0
  22. canvas_sdk/v1/data/fields.py +37 -0
  23. canvas_sdk/v1/data/imaging.py +18 -6
  24. canvas_sdk/v1/data/invoice.py +62 -0
  25. canvas_sdk/v1/data/lab.py +36 -12
  26. canvas_sdk/v1/data/line_item_transaction.py +83 -0
  27. canvas_sdk/v1/data/medication.py +6 -2
  28. canvas_sdk/v1/data/observation.py +9 -3
  29. canvas_sdk/v1/data/organization.py +3 -1
  30. canvas_sdk/v1/data/payment_collection.py +35 -0
  31. canvas_sdk/v1/data/posting.py +225 -0
  32. canvas_sdk/v1/data/protocol_override.py +6 -2
  33. canvas_sdk/v1/data/questionnaire.py +6 -2
  34. canvas_sdk/v1/data/utils.py +10 -0
  35. protobufs/canvas_generated/messages/effects.proto +1 -0
  36. {canvas-0.42.0.dist-info → canvas-0.43.0.dist-info}/WHEEL +0 -0
  37. {canvas-0.42.0.dist-info → canvas-0.43.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,62 @@
1
+ from django.db import models
2
+
3
+
4
+ class InvoiceRecipients(models.TextChoices):
5
+ """Choices for invoice recipients."""
6
+
7
+ PATIENT = "patient", "Patient"
8
+ GUARANTOR = "guarantor", "Guarantor"
9
+
10
+
11
+ class InvoiceStatus(models.TextChoices):
12
+ """Choices for invoice status."""
13
+
14
+ ACTIVE = "active", "Active"
15
+ ERROR = "error", "Error"
16
+ ARCHIVED = "archived", "Archived"
17
+
18
+
19
+ class InvoiceWorkflow(models.TextChoices):
20
+ """Choices for invoice workflow."""
21
+
22
+ AUTOMATED = "automated", "Automated"
23
+ ADHOC = "adhoc", "Adhoc"
24
+ BATCH = "batch", "Batch"
25
+
26
+
27
+ class InvoiceSentMeans(models.TextChoices):
28
+ """Choices for how the invoice was sent."""
29
+
30
+ MAIL = "mail", "Mail"
31
+ EMAIL = "e-mail", "E-mail"
32
+
33
+
34
+ class Invoice(models.Model):
35
+ """Represents a full invoice for a patient."""
36
+
37
+ class Meta:
38
+ managed = False
39
+ db_table = "canvas_sdk_data_quality_and_revenue_invoicefull_001"
40
+
41
+ dbid = models.BigIntegerField(primary_key=True)
42
+ originator = models.ForeignKey(
43
+ "v1.CanvasUser", on_delete=models.PROTECT, related_name="generated_invoices"
44
+ )
45
+ recipient = models.ForeignKey("v1.Patient", on_delete=models.CASCADE, related_name="invoices")
46
+ recipient_type = models.CharField(max_length=10, choices=InvoiceRecipients.choices)
47
+ total_amount = models.DecimalField(max_digits=8, decimal_places=2)
48
+ # invoice_pdf = models.FileField(blank=True, null=True, upload_to=invoice_upload)
49
+ status = models.CharField(max_length=10, choices=InvoiceStatus.choices)
50
+ workflow = models.CharField(max_length=10, choices=InvoiceWorkflow.choices)
51
+ # claims = models.ManyToManyField("v1.Claim", related_name="full_invoices")
52
+ error_message = models.TextField()
53
+ sent_mean = models.CharField(max_length=6, choices=InvoiceSentMeans.choices)
54
+
55
+
56
+ __exports__ = (
57
+ "Invoice",
58
+ "InvoiceRecipients",
59
+ "InvoiceStatus",
60
+ "InvoiceWorkflow",
61
+ "InvoiceSentMeans",
62
+ )
canvas_sdk/v1/data/lab.py CHANGED
@@ -61,9 +61,15 @@ class LabReport(models.Model):
61
61
  original_date = models.DateTimeField()
62
62
  date_performed = models.DateTimeField()
63
63
  custom_document_name = models.CharField()
64
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
65
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
66
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
64
+ originator = models.ForeignKey(
65
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
66
+ )
67
+ committer = models.ForeignKey(
68
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
69
+ )
70
+ entered_in_error = models.ForeignKey(
71
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
72
+ )
67
73
  deleted = models.BooleanField()
68
74
 
69
75
 
@@ -89,10 +95,16 @@ class LabReview(models.Model):
89
95
  dbid = models.BigIntegerField(primary_key=True)
90
96
  created = models.DateTimeField()
91
97
  modified = models.DateTimeField()
92
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
98
+ originator = models.ForeignKey(
99
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
100
+ )
93
101
  deleted = models.BooleanField()
94
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
95
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
102
+ committer = models.ForeignKey(
103
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
104
+ )
105
+ entered_in_error = models.ForeignKey(
106
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
107
+ )
96
108
  internal_comment = models.TextField()
97
109
  message_to_patient = models.CharField()
98
110
  status = models.CharField()
@@ -194,10 +206,16 @@ class LabOrder(models.Model):
194
206
  dbid = models.BigIntegerField(primary_key=True)
195
207
  created = models.DateTimeField()
196
208
  modified = models.DateTimeField()
197
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
209
+ originator = models.ForeignKey(
210
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
211
+ )
198
212
  deleted = models.BooleanField()
199
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
200
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
213
+ committer = models.ForeignKey(
214
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
215
+ )
216
+ entered_in_error = models.ForeignKey(
217
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
218
+ )
201
219
  patient = models.ForeignKey(
202
220
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="lab_orders", null=True
203
221
  )
@@ -240,10 +258,16 @@ class LabOrderReason(models.Model):
240
258
  dbid = models.BigIntegerField(primary_key=True)
241
259
  created = models.DateTimeField()
242
260
  modified = models.DateTimeField()
243
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
261
+ originator = models.ForeignKey(
262
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
263
+ )
244
264
  deleted = models.BooleanField()
245
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
246
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
265
+ committer = models.ForeignKey(
266
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
267
+ )
268
+ entered_in_error = models.ForeignKey(
269
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
270
+ )
247
271
  order = models.ForeignKey(
248
272
  LabOrder, on_delete=models.DO_NOTHING, related_name="reasons", null=True
249
273
  )
@@ -0,0 +1,83 @@
1
+ from django.db import models
2
+ from django.db.models import QuerySet
3
+
4
+
5
+ class AbstractLineItemQuerySet(models.QuerySet):
6
+ """AbstractLineItemQuerySet."""
7
+
8
+ def active(self) -> QuerySet:
9
+ """Filter out line items that have been entered in error."""
10
+ return self.filter(entered_in_error__isnull=True)
11
+
12
+
13
+ class AbstractLineItemTransaction(models.Model):
14
+ """Abstract class with common properties for both payments and adjustments."""
15
+
16
+ class Meta:
17
+ abstract = True
18
+
19
+ objects = AbstractLineItemQuerySet.as_manager()
20
+
21
+ dbid = models.BigIntegerField(primary_key=True)
22
+ posting = models.ForeignKey(
23
+ "v1.BasePosting", related_name="%(class)ss", on_delete=models.PROTECT
24
+ )
25
+ billing_line_item = models.ForeignKey(
26
+ "v1.BillingLineItem", related_name="%(class)ss", on_delete=models.PROTECT
27
+ )
28
+ amount = models.DecimalField(max_digits=8, decimal_places=2)
29
+
30
+ created = models.DateTimeField()
31
+ modified = models.DateTimeField()
32
+
33
+
34
+ class NewLineItemPayment(AbstractLineItemTransaction):
35
+ """Subclass that represents a payment on a billing line item."""
36
+
37
+ class Meta:
38
+ managed = False
39
+ db_table = "canvas_sdk_data_quality_and_revenue_newlineitempayment_001"
40
+
41
+ charged = models.DecimalField(max_digits=8, decimal_places=2)
42
+
43
+
44
+ class AbstractLineItemAdjustment(AbstractLineItemTransaction):
45
+ """Abstract subclass with common fields for both adjustment and transfer."""
46
+
47
+ class Meta:
48
+ abstract = True
49
+
50
+ code = models.CharField()
51
+ group = models.CharField()
52
+
53
+ deviated_from_posting_ruleset = models.BooleanField()
54
+
55
+
56
+ class NewLineItemAdjustment(AbstractLineItemAdjustment):
57
+ """Subclass for billing line item adjustments."""
58
+
59
+ class Meta:
60
+ managed = False
61
+ db_table = "canvas_sdk_data_quality_and_revenue_newlineitemadjustment_001"
62
+
63
+ write_off = models.BooleanField()
64
+
65
+
66
+ class LineItemTransfer(AbstractLineItemAdjustment):
67
+ """Subclass for billing line item balance transfer to other coverages or patient."""
68
+
69
+ class Meta:
70
+ managed = False
71
+ db_table = "canvas_sdk_data_quality_and_revenue_lineitemtransfer_001"
72
+
73
+ transfer_to = models.ForeignKey(
74
+ "v1.ClaimCoverage", related_name="transfers", on_delete=models.PROTECT, null=True
75
+ )
76
+ transfer_to_patient = models.BooleanField(default=False)
77
+
78
+
79
+ __exports__ = (
80
+ "NewLineItemPayment",
81
+ "NewLineItemAdjustment",
82
+ "LineItemTransfer",
83
+ )
@@ -44,8 +44,12 @@ class Medication(models.Model):
44
44
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="medications", null=True
45
45
  )
46
46
  deleted = models.BooleanField()
47
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
48
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
47
+ entered_in_error = models.ForeignKey(
48
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
49
+ )
50
+ committer = models.ForeignKey(
51
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
52
+ )
49
53
  status = models.CharField(choices=Status.choices)
50
54
  start_date = models.DateTimeField()
51
55
  end_date = models.DateTimeField()
@@ -34,9 +34,15 @@ class Observation(models.Model):
34
34
  dbid = models.BigIntegerField(primary_key=True)
35
35
  created = models.DateTimeField()
36
36
  modified = models.DateTimeField()
37
- originator = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
38
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
39
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
37
+ originator = models.ForeignKey(
38
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
39
+ )
40
+ committer = models.ForeignKey(
41
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
42
+ )
43
+ entered_in_error = models.ForeignKey(
44
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
45
+ )
40
46
  deleted = models.BooleanField()
41
47
  patient = models.ForeignKey(
42
48
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="observations", null=True
@@ -25,7 +25,9 @@ class Organization(models.Model):
25
25
  group_npi_number = models.CharField()
26
26
  group_taxonomy_number = models.CharField()
27
27
  include_zz_qualifier = models.BooleanField()
28
- main_location = models.OneToOneField("v1.PracticeLocation", on_delete=models.DO_NOTHING)
28
+ main_location = models.OneToOneField(
29
+ "v1.PracticeLocation", on_delete=models.DO_NOTHING, related_name="+"
30
+ )
29
31
 
30
32
 
31
33
  __exports__ = ("Organization",)
@@ -0,0 +1,35 @@
1
+ from django.db import models
2
+
3
+
4
+ class PostingMethods(models.TextChoices):
5
+ """PostingMethods."""
6
+
7
+ CASH = "cash", "Cash"
8
+ CHECK = "check", "Check"
9
+ CARD = "card", "Card"
10
+ OTHER = "other", "Other"
11
+
12
+
13
+ class PaymentCollection(models.Model):
14
+ """Stores the total collected amount and the payment method."""
15
+
16
+ class Meta:
17
+ managed = False
18
+ db_table = "canvas_sdk_data_quality_and_revenue_paymentcollection_001"
19
+
20
+ id = models.UUIDField()
21
+ dbid = models.BigIntegerField(primary_key=True)
22
+ total_collected = models.DecimalField(max_digits=8, decimal_places=2)
23
+ method = models.CharField(choices=PostingMethods.choices)
24
+
25
+ check_number = models.CharField()
26
+ check_date = models.DateField()
27
+ deposit_date = models.DateField()
28
+
29
+ description = models.TextField()
30
+
31
+ created = models.DateTimeField()
32
+ modified = models.DateTimeField()
33
+
34
+
35
+ __exports__ = ("PaymentCollection", "PostingMethods")
@@ -0,0 +1,225 @@
1
+ from decimal import Decimal
2
+ from typing import Self
3
+
4
+ from django.db import models
5
+
6
+ from canvas_sdk.v1.data.utils import quantize
7
+
8
+
9
+ class PostingQuerySet(models.QuerySet):
10
+ """A queryset for CoveragePosting objects."""
11
+
12
+ def active(self) -> Self:
13
+ """Return a queryset that filters for active postings."""
14
+ return self.filter(entered_in_error__isnull=True)
15
+
16
+
17
+ class BasePosting(models.Model):
18
+ """
19
+ Base model to aggregate multiple line item transactions on a claim.
20
+ """
21
+
22
+ class Meta:
23
+ managed = False
24
+ db_table = "canvas_sdk_data_quality_and_revenue_baseposting_001"
25
+
26
+ objects = PostingQuerySet.as_manager()
27
+
28
+ dbid = models.BigIntegerField(primary_key=True)
29
+ corrected_posting = models.ForeignKey(
30
+ "v1.BasePosting", related_name="correction_postings", on_delete=models.PROTECT, null=True
31
+ )
32
+
33
+ claim = models.ForeignKey("v1.Claim", related_name="postings", on_delete=models.PROTECT)
34
+ payment_collection = models.ForeignKey(
35
+ "v1.PaymentCollection", related_name="postings", null=True, on_delete=models.PROTECT
36
+ )
37
+
38
+ description = models.TextField(default="")
39
+
40
+ entered_in_error = models.ForeignKey(
41
+ "v1.CanvasUser", on_delete=models.PROTECT, null=True, blank=True
42
+ )
43
+
44
+ created = models.DateTimeField()
45
+ modified = models.DateTimeField()
46
+
47
+ @property
48
+ def paid_amount(self) -> Decimal:
49
+ """Returns the total amount paid for this posting."""
50
+ return quantize(sum(lip.amount for lip in self.newlineitempayments.all()))
51
+
52
+ @property
53
+ def contractual_adjusted_amount(self) -> Decimal:
54
+ """Returns the total amount of contractual adjustments for this posting."""
55
+ return quantize(
56
+ sum(lia.amount for lia in self.newlineitemadjustments.all() if lia.write_off)
57
+ )
58
+
59
+ @property
60
+ def non_write_off_adjusted_amount(self) -> Decimal | int:
61
+ """Returns the total amount of non-write-off adjustments for this posting."""
62
+ return sum(lia.amount for lia in self.newlineitemadjustments.all() if not lia.write_off)
63
+
64
+ @property
65
+ def transferred_amount(self) -> Decimal:
66
+ """Returns the total amount transferred for this posting."""
67
+ return quantize(sum(lit.amount for lit in self.lineitemtransfers.all()))
68
+
69
+ @property
70
+ def transferred_to_patient_amount(self) -> Decimal | int:
71
+ """Returns the total amount transferred to the patient."""
72
+ transfers = [trans for trans in self.lineitemtransfers.all() if trans.transfer_to_patient]
73
+ return sum(lit.amount for lit in transfers)
74
+
75
+ @property
76
+ def transferred_to_coverage_amount(self) -> Decimal | int:
77
+ """Returns the total amount transferred to another coverage."""
78
+ transfers = [trans for trans in self.lineitemtransfers.all() if trans.transfer_to]
79
+ return sum(lit.amount for lit in transfers)
80
+
81
+ @property
82
+ def adjusted_and_transferred_amount(self) -> Decimal:
83
+ """Returns the charges amount per claim for a patient posting."""
84
+ return self.contractual_adjusted_amount + self.transferred_amount
85
+
86
+ @property
87
+ def posted_amount(self) -> Decimal:
88
+ """Property to compute how much was posted with this posting: sums all payments and write-off adjustments."""
89
+ return self.paid_amount + self.contractual_adjusted_amount + self.transferred_amount
90
+
91
+
92
+ class CoveragePosting(BasePosting):
93
+ """Represents an insurance payment/adjustment on a claim level."""
94
+
95
+ class Meta:
96
+ managed = False
97
+ db_table = "canvas_sdk_data_quality_and_revenue_coverageposting_001"
98
+
99
+ remittance = models.ForeignKey(
100
+ "v1.BaseRemittanceAdvice", related_name="postings", on_delete=models.PROTECT, null=True
101
+ )
102
+ claim_coverage = models.ForeignKey(
103
+ "v1.ClaimCoverage", related_name="postings", on_delete=models.PROTECT
104
+ )
105
+
106
+ crossover_carrier = models.CharField()
107
+ crossover_id = models.CharField()
108
+ payer_icn = models.CharField()
109
+ position_in_era = models.PositiveIntegerField()
110
+
111
+
112
+ class PatientPosting(BasePosting):
113
+ """A model that represents a patient payment/adjustment on a claim level."""
114
+
115
+ class Meta:
116
+ managed = False
117
+ db_table = "canvas_sdk_data_quality_and_revenue_patientposting_001"
118
+
119
+ claim_patient = models.ForeignKey(
120
+ "v1.ClaimPatient", related_name="postings", on_delete=models.PROTECT
121
+ )
122
+ patient_payment = models.ForeignKey(
123
+ "v1.BulkPatientPosting", related_name="postings", on_delete=models.PROTECT, null=True
124
+ )
125
+
126
+ copay = models.ForeignKey(
127
+ "v1.BulkPatientPosting", related_name="copays", on_delete=models.PROTECT, null=True
128
+ )
129
+
130
+ @property
131
+ def discounted_amount(self) -> Decimal:
132
+ """Returns the discounted amount per claim for a patient bulk posting."""
133
+ if not self.patient_payment or not self.patient_payment.discount:
134
+ return Decimal("0")
135
+
136
+ discount = self.patient_payment.discount
137
+ return quantize(
138
+ sum(
139
+ lia.amount
140
+ for lia in self.newlineitemadjustments.all()
141
+ if (
142
+ lia.write_off
143
+ and (lia.group, lia.code)
144
+ == (discount.adjustment_group, discount.adjustment_code)
145
+ )
146
+ )
147
+ )
148
+
149
+ @property
150
+ def charges_amount(self) -> Decimal:
151
+ """Returns the charges amount per claim for a patient posting."""
152
+ return self.discounted_amount + self.paid_amount
153
+
154
+
155
+ class AbstractBulkPosting(models.Model):
156
+ """Patient and Insurance bulk posting shared columns."""
157
+
158
+ class Meta:
159
+ abstract = True
160
+
161
+ id = models.UUIDField()
162
+ dbid = models.BigIntegerField(primary_key=True)
163
+
164
+ payment_collection = models.OneToOneField(
165
+ "v1.PaymentCollection", related_name="%(class)s", on_delete=models.PROTECT
166
+ )
167
+
168
+ total_paid = models.DecimalField(max_digits=8, decimal_places=2)
169
+
170
+ created = models.DateTimeField()
171
+ modified = models.DateTimeField()
172
+
173
+
174
+ class BulkPatientPosting(AbstractBulkPosting):
175
+ """Model to aggregate bulk patient payments on multiple claims."""
176
+
177
+ class Meta:
178
+ managed = False
179
+ db_table = "canvas_sdk_data_quality_and_revenue_bulkpatientposting_001"
180
+
181
+ discount = models.ForeignKey(
182
+ "v1.Discount", related_name="patient_postings", null=True, on_delete=models.SET_NULL
183
+ )
184
+ payer = models.ForeignKey("v1.Patient", related_name="payments", on_delete=models.PROTECT)
185
+
186
+ @property
187
+ def total_posted_amount(self) -> Decimal:
188
+ """Property to compute how much was posted with all associated postings."""
189
+ postings = self.postings.active()
190
+ return quantize(sum(posting.posted_amount for posting in postings))
191
+
192
+ @property
193
+ def discounted_amount(self) -> Decimal:
194
+ """Returns the sum of discounted amounts for every posting created with this collection."""
195
+ postings = self.postings.active()
196
+ return quantize(sum(posting.discounted_amount for posting in postings))
197
+
198
+
199
+ class BaseRemittanceAdvice(AbstractBulkPosting):
200
+ """Manual and Electronic Shared columns."""
201
+
202
+ class Meta:
203
+ managed = False
204
+ db_table = "canvas_sdk_data_quality_and_revenue_baseremittanceadvice_001"
205
+
206
+ transactor = models.ForeignKey(
207
+ "v1.Transactor", related_name="remits", null=True, on_delete=models.PROTECT
208
+ )
209
+
210
+ era_id = models.CharField(max_length=255, null=True, blank=True, db_index=True)
211
+
212
+ @property
213
+ def total_posted_amount(self) -> Decimal:
214
+ """Property to compute how much was posted with all associated postings."""
215
+ postings = self.postings.active()
216
+ return quantize(sum(posting.posted_amount for posting in postings))
217
+
218
+
219
+ __exports__ = (
220
+ "BasePosting",
221
+ "CoveragePosting",
222
+ "PatientPosting",
223
+ "BulkPatientPosting",
224
+ "BaseRemittanceAdvice",
225
+ )
@@ -48,8 +48,12 @@ class ProtocolOverride(models.Model):
48
48
  created = models.DateTimeField()
49
49
  modified = models.DateTimeField()
50
50
  deleted = models.BooleanField()
51
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
52
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
51
+ committer = models.ForeignKey(
52
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
53
+ )
54
+ entered_in_error = models.ForeignKey(
55
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
56
+ )
53
57
  patient = models.ForeignKey(
54
58
  "v1.Patient", on_delete=models.DO_NOTHING, related_name="protocol_overrides", null=True
55
59
  )
@@ -148,8 +148,12 @@ class Interview(models.Model):
148
148
  id = models.UUIDField()
149
149
  dbid = models.BigIntegerField(primary_key=True)
150
150
  deleted = models.BooleanField()
151
- committer = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
152
- entered_in_error = models.ForeignKey("v1.CanvasUser", on_delete=models.DO_NOTHING, null=True)
151
+ committer = models.ForeignKey(
152
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
153
+ )
154
+ entered_in_error = models.ForeignKey(
155
+ "v1.CanvasUser", on_delete=models.DO_NOTHING, null=True, related_name="+"
156
+ )
153
157
  status = models.CharField()
154
158
  name = models.CharField()
155
159
  language_id = models.BigIntegerField()
@@ -0,0 +1,10 @@
1
+ from collections.abc import Sequence
2
+ from decimal import Decimal
3
+
4
+
5
+ def quantize(deci: Decimal | float | str | tuple[int, Sequence[int], int]) -> Decimal:
6
+ """Rounds a Decimal value to two decimal places."""
7
+ return Decimal(deci).quantize(Decimal(".01"))
8
+
9
+
10
+ __exports__ = ()
@@ -281,6 +281,7 @@ enum EffectType {
281
281
 
282
282
  PATIENT_METADATA__CREATE_ADDITIONAL_FIELDS = 6010;
283
283
  UPSERT_PATIENT_METADATA = 6011;
284
+ CREATE_PATIENT_EXTERNAL_IDENTIFIER = 6012;
284
285
  }
285
286
 
286
287
  message Effect {