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.
- {canvas-0.42.0.dist-info → canvas-0.43.0.dist-info}/METADATA +1 -1
- {canvas-0.42.0.dist-info → canvas-0.43.0.dist-info}/RECORD +37 -27
- canvas_generated/messages/effects_pb2.py +2 -2
- canvas_generated/messages/effects_pb2.pyi +2 -0
- canvas_sdk/effects/patient/__init__.py +10 -2
- canvas_sdk/effects/patient/base.py +20 -1
- canvas_sdk/effects/patient/create_patient_external_identifier.py +40 -0
- canvas_sdk/effects/protocol_card/__init__.py +4 -1
- canvas_sdk/effects/protocol_card/protocol_card.py +2 -0
- canvas_sdk/utils/http.py +46 -2
- canvas_sdk/v1/data/__init__.py +29 -0
- canvas_sdk/v1/data/allergy_intolerance.py +6 -2
- canvas_sdk/v1/data/assessment.py +7 -3
- canvas_sdk/v1/data/billing.py +1 -1
- canvas_sdk/v1/data/claim.py +321 -0
- canvas_sdk/v1/data/claim_line_item.py +140 -0
- canvas_sdk/v1/data/command.py +12 -3
- canvas_sdk/v1/data/condition.py +7 -2
- canvas_sdk/v1/data/detected_issue.py +9 -3
- canvas_sdk/v1/data/device.py +9 -3
- canvas_sdk/v1/data/discount.py +21 -0
- canvas_sdk/v1/data/fields.py +37 -0
- canvas_sdk/v1/data/imaging.py +18 -6
- canvas_sdk/v1/data/invoice.py +62 -0
- canvas_sdk/v1/data/lab.py +36 -12
- canvas_sdk/v1/data/line_item_transaction.py +83 -0
- canvas_sdk/v1/data/medication.py +6 -2
- canvas_sdk/v1/data/observation.py +9 -3
- canvas_sdk/v1/data/organization.py +3 -1
- canvas_sdk/v1/data/payment_collection.py +35 -0
- canvas_sdk/v1/data/posting.py +225 -0
- canvas_sdk/v1/data/protocol_override.py +6 -2
- canvas_sdk/v1/data/questionnaire.py +6 -2
- canvas_sdk/v1/data/utils.py +10 -0
- protobufs/canvas_generated/messages/effects.proto +1 -0
- {canvas-0.42.0.dist-info → canvas-0.43.0.dist-info}/WHEEL +0 -0
- {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(
|
|
65
|
-
|
|
66
|
-
|
|
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(
|
|
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(
|
|
95
|
-
|
|
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(
|
|
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(
|
|
200
|
-
|
|
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(
|
|
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(
|
|
246
|
-
|
|
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
|
+
)
|
canvas_sdk/v1/data/medication.py
CHANGED
|
@@ -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(
|
|
48
|
-
|
|
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(
|
|
38
|
-
|
|
39
|
-
|
|
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(
|
|
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(
|
|
52
|
-
|
|
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(
|
|
152
|
-
|
|
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__ = ()
|
|
File without changes
|
|
File without changes
|