1177 lines
44 KiB
Python
1177 lines
44 KiB
Python
# 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",
|
||
},
|
||
),
|
||
]
|