Marwan Alwali 4d06ca4b5e update
2025-09-20 14:26:19 +03:00

1177 lines
44 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Generated by Django 5.2.6 on 2025-09-19 10:58
import billing.utils
import django.db.models.deletion
import django.utils.timezone
import uuid
from decimal import Decimal
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="BillLineItem",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"line_item_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique line item identifier",
unique=True,
),
),
(
"line_number",
models.PositiveIntegerField(help_text="Line item number"),
),
("service_date", models.DateField(help_text="Service date")),
(
"service_code",
models.CharField(
help_text="Service code (CPT, HCPCS, etc.)", max_length=20
),
),
(
"service_description",
models.CharField(help_text="Service description", max_length=200),
),
(
"service_category",
models.CharField(
choices=[
("EVALUATION", "Evaluation & Management"),
("SURGERY", "Surgery"),
("RADIOLOGY", "Radiology"),
("PATHOLOGY", "Pathology & Laboratory"),
("MEDICINE", "Medicine"),
("ANESTHESIA", "Anesthesia"),
("SUPPLIES", "Medical Supplies"),
("PHARMACY", "Pharmacy"),
("ROOM_BOARD", "Room & Board"),
("NURSING", "Nursing Services"),
("THERAPY", "Therapy Services"),
("EMERGENCY", "Emergency Services"),
("AMBULANCE", "Ambulance Services"),
("DME", "Durable Medical Equipment"),
("OTHER", "Other Services"),
],
help_text="Service category",
max_length=30,
),
),
(
"quantity",
models.DecimalField(
decimal_places=2,
default=Decimal("1.00"),
help_text="Quantity of service",
max_digits=10,
),
),
(
"unit_of_measure",
models.CharField(
choices=[
("EACH", "Each"),
("UNIT", "Unit"),
("HOUR", "Hour"),
("DAY", "Day"),
("VISIT", "Visit"),
("PROCEDURE", "Procedure"),
("DOSE", "Dose"),
("MILE", "Mile"),
("MINUTE", "Minute"),
],
default="EACH",
help_text="Unit of measure",
max_length=20,
),
),
(
"unit_price",
models.DecimalField(
decimal_places=2, help_text="Unit price", max_digits=10
),
),
(
"total_price",
models.DecimalField(
decimal_places=2,
help_text="Total price (quantity × unit price)",
max_digits=12,
),
),
(
"modifier_1",
models.CharField(
blank=True, help_text="First modifier", max_length=5, null=True
),
),
(
"modifier_2",
models.CharField(
blank=True, help_text="Second modifier", max_length=5, null=True
),
),
(
"modifier_3",
models.CharField(
blank=True, help_text="Third modifier", max_length=5, null=True
),
),
(
"modifier_4",
models.CharField(
blank=True, help_text="Fourth modifier", max_length=5, null=True
),
),
(
"primary_diagnosis",
models.CharField(
blank=True,
help_text="Primary diagnosis code",
max_length=20,
null=True,
),
),
(
"secondary_diagnoses",
models.JSONField(
default=list, help_text="Secondary diagnosis codes"
),
),
(
"place_of_service",
models.CharField(
choices=[
("11", "Office"),
("12", "Home"),
("21", "Inpatient Hospital"),
("22", "Outpatient Hospital"),
("23", "Emergency Room"),
("24", "Ambulatory Surgical Center"),
("25", "Birthing Center"),
("26", "Military Treatment Facility"),
("31", "Skilled Nursing Facility"),
("32", "Nursing Facility"),
("33", "Custodial Care Facility"),
("34", "Hospice"),
("41", "Ambulance - Land"),
("42", "Ambulance - Air or Water"),
("49", "Independent Clinic"),
("50", "Federally Qualified Health Center"),
("51", "Inpatient Psychiatric Facility"),
("52", "Psychiatric Facility-Partial Hospitalization"),
("53", "Community Mental Health Center"),
("54", "Intermediate Care Facility/Mentally Retarded"),
("55", "Residential Substance Abuse Treatment Facility"),
("56", "Psychiatric Residential Treatment Center"),
(
"57",
"Non-residential Substance Abuse Treatment Facility",
),
("60", "Mass Immunization Center"),
("61", "Comprehensive Inpatient Rehabilitation Facility"),
("62", "Comprehensive Outpatient Rehabilitation Facility"),
("65", "End-Stage Renal Disease Treatment Facility"),
("71", "Public Health Clinic"),
("72", "Rural Health Clinic"),
("81", "Independent Laboratory"),
("99", "Other Place of Service"),
],
default="22",
help_text="Place of service code",
max_length=5,
),
),
(
"revenue_code",
models.CharField(
blank=True,
help_text="Revenue code for facility billing",
max_length=4,
null=True,
),
),
(
"ndc_code",
models.CharField(
blank=True,
help_text="National Drug Code",
max_length=20,
null=True,
),
),
(
"drug_quantity",
models.DecimalField(
blank=True,
decimal_places=3,
help_text="Drug quantity",
max_digits=10,
null=True,
),
),
(
"drug_unit",
models.CharField(
blank=True,
help_text="Drug unit of measure",
max_length=10,
null=True,
),
),
(
"status",
models.CharField(
choices=[
("ACTIVE", "Active"),
("DENIED", "Denied"),
("ADJUSTED", "Adjusted"),
("VOIDED", "Voided"),
],
default="ACTIVE",
help_text="Line item status",
max_length=20,
),
),
(
"notes",
models.TextField(
blank=True, help_text="Line item notes", null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Bill Line Item",
"verbose_name_plural": "Bill Line Items",
"db_table": "billing_bill_line_item",
"ordering": ["line_number"],
},
),
migrations.CreateModel(
name="ClaimStatusUpdate",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"update_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique update identifier",
unique=True,
),
),
(
"previous_status",
models.CharField(help_text="Previous claim status", max_length=20),
),
(
"new_status",
models.CharField(help_text="New claim status", max_length=20),
),
(
"status_date",
models.DateTimeField(
default=django.utils.timezone.now,
help_text="Status change date and time",
),
),
(
"update_source",
models.CharField(
choices=[
("MANUAL", "Manual Update"),
("EDI", "EDI Response"),
("PHONE", "Phone Call"),
("PORTAL", "Insurance Portal"),
("EMAIL", "Email"),
("FAX", "Fax"),
("MAIL", "Mail"),
("SYSTEM", "System Generated"),
],
help_text="Update source",
max_length=20,
),
),
(
"response_code",
models.CharField(
blank=True,
help_text="Insurance response code",
max_length=20,
null=True,
),
),
(
"response_message",
models.TextField(
blank=True, help_text="Insurance response message", null=True
),
),
(
"allowed_amount",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Updated allowed amount",
max_digits=12,
null=True,
),
),
(
"paid_amount",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Updated paid amount",
max_digits=12,
null=True,
),
),
(
"patient_responsibility",
models.DecimalField(
blank=True,
decimal_places=2,
help_text="Updated patient responsibility",
max_digits=12,
null=True,
),
),
(
"notes",
models.TextField(
blank=True, help_text="Update notes and comments", null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
],
options={
"verbose_name": "Claim Status Update",
"verbose_name_plural": "Claim Status Updates",
"db_table": "billing_claim_status_update",
"ordering": ["-status_date"],
},
),
migrations.CreateModel(
name="InsuranceClaim",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"claim_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique claim identifier",
unique=True,
),
),
(
"claim_number",
models.CharField(
help_text="Insurance claim number", max_length=30, unique=True
),
),
(
"claim_type",
models.CharField(
choices=[
("PRIMARY", "Primary Claim"),
("SECONDARY", "Secondary Claim"),
("TERTIARY", "Tertiary Claim"),
("CORRECTED", "Corrected Claim"),
("VOID", "Void Claim"),
("REPLACEMENT", "Replacement Claim"),
],
default="PRIMARY",
help_text="Claim type",
max_length=20,
),
),
(
"submission_date",
models.DateField(help_text="Claim submission date"),
),
("service_date_from", models.DateField(help_text="Service date from")),
("service_date_to", models.DateField(help_text="Service date to")),
(
"billed_amount",
models.DecimalField(
decimal_places=2, help_text="Total billed amount", max_digits=12
),
),
(
"allowed_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Insurance allowed amount",
max_digits=12,
),
),
(
"paid_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Insurance paid amount",
max_digits=12,
),
),
(
"patient_responsibility",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Patient responsibility amount",
max_digits=12,
),
),
(
"deductible_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Deductible amount",
max_digits=12,
),
),
(
"coinsurance_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Coinsurance amount",
max_digits=12,
),
),
(
"copay_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Copay amount",
max_digits=12,
),
),
(
"status",
models.CharField(
choices=[
("DRAFT", "Draft"),
("SUBMITTED", "Submitted"),
("PENDING", "Pending"),
("PROCESSING", "Processing"),
("PAID", "Paid"),
("DENIED", "Denied"),
("REJECTED", "Rejected"),
("APPEALED", "Appealed"),
("VOIDED", "Voided"),
],
default="DRAFT",
help_text="Claim status",
max_length=20,
),
),
(
"clearinghouse",
models.CharField(
blank=True,
help_text="Clearinghouse used for submission",
max_length=100,
null=True,
),
),
(
"batch_number",
models.CharField(
blank=True, help_text="Batch number", max_length=50, null=True
),
),
(
"response_date",
models.DateField(
blank=True, help_text="Insurance response date", null=True
),
),
(
"check_number",
models.CharField(
blank=True,
help_text="Insurance check number",
max_length=50,
null=True,
),
),
(
"check_date",
models.DateField(
blank=True, help_text="Insurance check date", null=True
),
),
(
"denial_reason",
models.CharField(
blank=True, help_text="Denial reason", max_length=200, null=True
),
),
(
"denial_code",
models.CharField(
blank=True, help_text="Denial code", max_length=20, null=True
),
),
(
"prior_auth_number",
models.CharField(
blank=True,
help_text="Prior authorization number",
max_length=50,
null=True,
),
),
(
"notes",
models.TextField(
blank=True, help_text="Claim notes and comments", null=True
),
),
(
"resubmission_count",
models.PositiveIntegerField(
default=0, help_text="Number of resubmissions"
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Insurance Claim",
"verbose_name_plural": "Insurance Claims",
"db_table": "billing_insurance_claim",
"ordering": ["-submission_date"],
},
),
migrations.CreateModel(
name="MedicalBill",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"bill_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique bill identifier",
unique=True,
),
),
(
"bill_number",
models.CharField(
help_text="Medical bill number", max_length=20, unique=True
),
),
(
"bill_type",
models.CharField(
choices=[
("INPATIENT", "Inpatient"),
("OUTPATIENT", "Outpatient"),
("EMERGENCY", "Emergency"),
("SURGERY", "Surgery"),
("LABORATORY", "Laboratory"),
("RADIOLOGY", "Radiology"),
("PHARMACY", "Pharmacy"),
("PROFESSIONAL", "Professional Services"),
("FACILITY", "Facility Charges"),
("ANCILLARY", "Ancillary Services"),
],
help_text="Bill type",
max_length=20,
),
),
("service_date_from", models.DateField(help_text="Service date from")),
("service_date_to", models.DateField(help_text="Service date to")),
(
"bill_date",
models.DateField(
default=django.utils.timezone.now, help_text="Bill date"
),
),
("due_date", models.DateField(help_text="Payment due date")),
(
"subtotal",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Subtotal amount",
max_digits=12,
),
),
(
"tax_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Tax amount",
max_digits=12,
),
),
(
"discount_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Discount amount",
max_digits=12,
),
),
(
"adjustment_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Adjustment amount",
max_digits=12,
),
),
(
"total_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Total bill amount",
max_digits=12,
),
),
(
"paid_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Amount paid",
max_digits=12,
),
),
(
"balance_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Balance amount",
max_digits=12,
),
),
(
"status",
models.CharField(
choices=[
("DRAFT", "Draft"),
("PENDING", "Pending"),
("SUBMITTED", "Submitted"),
("PARTIAL_PAID", "Partially Paid"),
("PAID", "Paid"),
("OVERDUE", "Overdue"),
("COLLECTIONS", "Collections"),
("WRITTEN_OFF", "Written Off"),
("CANCELLED", "Cancelled"),
],
default="DRAFT",
help_text="Bill status",
max_length=20,
),
),
(
"notes",
models.TextField(
blank=True, help_text="Billing notes and comments", null=True
),
),
(
"payment_terms",
models.CharField(
choices=[
("NET_30", "Net 30 Days"),
("NET_60", "Net 60 Days"),
("NET_90", "Net 90 Days"),
("IMMEDIATE", "Immediate"),
("CUSTOM", "Custom Terms"),
],
default="NET_30",
help_text="Payment terms",
max_length=20,
),
),
(
"collection_status",
models.CharField(
choices=[
("NONE", "None"),
("FIRST_NOTICE", "First Notice"),
("SECOND_NOTICE", "Second Notice"),
("FINAL_NOTICE", "Final Notice"),
("COLLECTIONS", "Collections"),
("LEGAL", "Legal Action"),
],
default="NONE",
help_text="Collection status",
max_length=20,
),
),
(
"last_statement_date",
models.DateField(
blank=True, help_text="Last statement date", null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Medical Bill",
"verbose_name_plural": "Medical Bills",
"db_table": "billing_medical_bill",
"ordering": ["-bill_date"],
},
),
migrations.CreateModel(
name="Payment",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"payment_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique payment identifier",
unique=True,
),
),
(
"payment_number",
models.CharField(
help_text="Payment number", max_length=20, unique=True
),
),
("payment_date", models.DateField(help_text="Payment date")),
(
"payment_amount",
models.DecimalField(
decimal_places=2, help_text="Payment amount", max_digits=12
),
),
(
"payment_method",
models.CharField(
choices=[
("CASH", "Cash"),
("CHECK", "Check"),
("CREDIT_CARD", "Credit Card"),
("DEBIT_CARD", "Debit Card"),
("BANK_TRANSFER", "Bank Transfer"),
("ACH", "ACH Transfer"),
("WIRE", "Wire Transfer"),
("MONEY_ORDER", "Money Order"),
("INSURANCE", "Insurance Payment"),
("ADJUSTMENT", "Adjustment"),
("WRITE_OFF", "Write Off"),
("OTHER", "Other"),
],
help_text="Payment method",
max_length=20,
),
),
(
"payment_source",
models.CharField(
choices=[
("PATIENT", "Patient"),
("INSURANCE", "Insurance"),
("GUARANTOR", "Guarantor"),
("GOVERNMENT", "Government"),
("CHARITY", "Charity"),
("OTHER", "Other"),
],
help_text="Payment source",
max_length=20,
),
),
(
"check_number",
models.CharField(
blank=True, help_text="Check number", max_length=50, null=True
),
),
(
"bank_name",
models.CharField(
blank=True, help_text="Bank name", max_length=100, null=True
),
),
(
"routing_number",
models.CharField(
blank=True,
help_text="Bank routing number",
max_length=20,
null=True,
),
),
(
"card_type",
models.CharField(
blank=True,
choices=[
("VISA", "Visa"),
("MASTERCARD", "MasterCard"),
("AMEX", "American Express"),
("DISCOVER", "Discover"),
("OTHER", "Other"),
],
help_text="Credit card type",
max_length=20,
null=True,
),
),
(
"card_last_four",
models.CharField(
blank=True,
help_text="Last four digits of card",
max_length=4,
null=True,
),
),
(
"authorization_code",
models.CharField(
blank=True,
help_text="Authorization code",
max_length=20,
null=True,
),
),
(
"transaction_id",
models.CharField(
blank=True, help_text="Transaction ID", max_length=50, null=True
),
),
(
"eob_number",
models.CharField(
blank=True,
help_text="Explanation of Benefits number",
max_length=50,
null=True,
),
),
(
"status",
models.CharField(
choices=[
("PENDING", "Pending"),
("PROCESSED", "Processed"),
("CLEARED", "Cleared"),
("BOUNCED", "Bounced"),
("REVERSED", "Reversed"),
("REFUNDED", "Refunded"),
],
default="PENDING",
help_text="Payment status",
max_length=20,
),
),
(
"deposit_date",
models.DateField(blank=True, help_text="Deposit date", null=True),
),
(
"deposit_slip",
models.CharField(
blank=True,
help_text="Deposit slip number",
max_length=50,
null=True,
),
),
(
"notes",
models.TextField(
blank=True, help_text="Payment notes and comments", null=True
),
),
(
"refund_amount",
models.DecimalField(
decimal_places=2,
default=Decimal("0.00"),
help_text="Refund amount",
max_digits=12,
),
),
(
"refund_date",
models.DateField(blank=True, help_text="Refund date", null=True),
),
(
"refund_reason",
models.CharField(
blank=True, help_text="Refund reason", max_length=200, null=True
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
],
options={
"verbose_name": "Payment",
"verbose_name_plural": "Payments",
"db_table": "billing_payment",
"ordering": ["-payment_date"],
},
),
migrations.CreateModel(
name="BillingConfiguration",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"config_id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
help_text="Unique configuration identifier",
unique=True,
),
),
(
"default_payment_terms",
models.CharField(
choices=[
("NET_30", "Net 30 Days"),
("NET_60", "Net 60 Days"),
("NET_90", "Net 90 Days"),
("IMMEDIATE", "Immediate"),
],
default="NET_30",
help_text="Default payment terms",
max_length=20,
),
),
(
"tax_rate",
models.DecimalField(
decimal_places=4,
default=Decimal("0.0000"),
help_text="Default tax rate (as decimal, e.g., 0.0825 for 8.25%)",
max_digits=5,
),
),
(
"tax_exempt",
models.BooleanField(
default=True, help_text="Organization is tax exempt"
),
),
(
"statement_frequency",
models.CharField(
choices=[
("MONTHLY", "Monthly"),
("QUARTERLY", "Quarterly"),
("ON_DEMAND", "On Demand"),
],
default="MONTHLY",
help_text="Statement frequency",
max_length=20,
),
),
(
"statement_message",
models.TextField(
blank=True, help_text="Default statement message", null=True
),
),
(
"first_notice_days",
models.PositiveIntegerField(
default=30, help_text="Days after due date for first notice"
),
),
(
"second_notice_days",
models.PositiveIntegerField(
default=60, help_text="Days after due date for second notice"
),
),
(
"final_notice_days",
models.PositiveIntegerField(
default=90, help_text="Days after due date for final notice"
),
),
(
"collections_days",
models.PositiveIntegerField(
default=120,
help_text="Days after due date to send to collections",
),
),
(
"apply_interest",
models.BooleanField(
default=False, help_text="Apply interest to overdue accounts"
),
),
(
"interest_rate",
models.DecimalField(
decimal_places=4,
default=Decimal("0.0000"),
help_text="Monthly interest rate (as decimal)",
max_digits=5,
),
),
(
"accept_credit_cards",
models.BooleanField(
default=True, help_text="Accept credit card payments"
),
),
(
"accept_ach",
models.BooleanField(default=True, help_text="Accept ACH payments"),
),
(
"payment_portal_enabled",
models.BooleanField(
default=True, help_text="Enable online payment portal"
),
),
(
"auto_submit_claims",
models.BooleanField(
default=False, help_text="Automatically submit claims"
),
),
(
"claim_submission_frequency",
models.CharField(
choices=[
("DAILY", "Daily"),
("WEEKLY", "Weekly"),
("MANUAL", "Manual"),
],
default="DAILY",
help_text="Claim submission frequency",
max_length=20,
),
),
(
"primary_clearinghouse",
models.CharField(
blank=True,
help_text="Primary clearinghouse",
max_length=100,
null=True,
),
),
(
"secondary_clearinghouse",
models.CharField(
blank=True,
help_text="Secondary clearinghouse",
max_length=100,
null=True,
),
),
(
"aging_buckets",
models.JSONField(
default=billing.utils.default_aging_buckets,
help_text="Aging report buckets in days",
),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"created_by",
models.ForeignKey(
blank=True,
help_text="User who created the configuration",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="created_billing_configurations",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
"verbose_name": "Billing Configuration",
"verbose_name_plural": "Billing Configurations",
"db_table": "billing_configuration",
},
),
]