agdar/finance/migrations/0001_initial.py
2025-11-02 14:35:35 +03:00

760 lines
29 KiB
Python

# Generated by Django 5.2.7 on 2025-10-27 10:50
import django.db.models.deletion
import simple_history.models
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("appointments", "0001_initial"),
("core", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="Payer",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True, verbose_name="Created At")),
("updated_at", models.DateTimeField(auto_now=True, verbose_name="Updated At")),
("name", models.CharField(max_length=200, verbose_name="Payer Name")),
(
"payer_type",
models.CharField(
choices=[
("SELF", "Self Pay"),
("INSURANCE", "Insurance"),
("GOVERNMENT", "Government"),
("CORPORATE", "Corporate"),
],
default="SELF",
max_length=20,
verbose_name="Payer Type",
),
),
(
"policy_number",
models.CharField(blank=True, max_length=100, verbose_name="Policy Number"),
),
(
"coverage_percentage",
models.DecimalField(
decimal_places=2,
default=0,
help_text="Percentage of costs covered (0-100)",
max_digits=5,
verbose_name="Coverage %",
),
),
("is_active", models.BooleanField(default=True, verbose_name="Is Active")),
("notes", models.TextField(blank=True, verbose_name="Notes")),
(
"patient",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="payers",
to="core.patient",
verbose_name="Patient",
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="%(app_label)s_%(class)s_related",
to="core.tenant",
verbose_name="Tenant",
),
),
],
options={
"verbose_name": "Payer",
"verbose_name_plural": "Payers",
"ordering": ["patient", "name"],
},
),
migrations.CreateModel(
name="Invoice",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True, verbose_name="Created At")),
("updated_at", models.DateTimeField(auto_now=True, verbose_name="Updated At")),
(
"invoice_number",
models.CharField(
editable=False, max_length=20, unique=True, verbose_name="Invoice Number"
),
),
("issue_date", models.DateField(verbose_name="Issue Date")),
("due_date", models.DateField(verbose_name="Due Date")),
(
"subtotal",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Subtotal"
),
),
(
"tax",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Tax (VAT)"
),
),
(
"discount",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Discount"
),
),
(
"total",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Total"
),
),
(
"status",
models.CharField(
choices=[
("DRAFT", "Draft"),
("ISSUED", "Issued"),
("PAID", "Paid"),
("PARTIALLY_PAID", "Partially Paid"),
("CANCELLED", "Cancelled"),
("OVERDUE", "Overdue"),
],
default="DRAFT",
max_length=20,
verbose_name="Status",
),
),
("notes", models.TextField(blank=True, verbose_name="Notes")),
(
"appointment",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="invoices",
to="appointments.appointment",
verbose_name="Appointment",
),
),
(
"patient",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="invoices",
to="core.patient",
verbose_name="Patient",
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="%(app_label)s_%(class)s_related",
to="core.tenant",
verbose_name="Tenant",
),
),
(
"payer",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="invoices",
to="finance.payer",
verbose_name="Payer",
),
),
],
options={
"verbose_name": "Invoice",
"verbose_name_plural": "Invoices",
"ordering": ["-issue_date", "-invoice_number"],
},
),
migrations.CreateModel(
name="HistoricalInvoice",
fields=[
(
"id",
models.UUIDField(
db_index=True, default=uuid.uuid4, editable=False, verbose_name="ID"
),
),
(
"created_at",
models.DateTimeField(blank=True, editable=False, verbose_name="Created At"),
),
(
"updated_at",
models.DateTimeField(blank=True, editable=False, verbose_name="Updated At"),
),
(
"invoice_number",
models.CharField(
db_index=True, editable=False, max_length=20, verbose_name="Invoice Number"
),
),
("issue_date", models.DateField(verbose_name="Issue Date")),
("due_date", models.DateField(verbose_name="Due Date")),
(
"subtotal",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Subtotal"
),
),
(
"tax",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Tax (VAT)"
),
),
(
"discount",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Discount"
),
),
(
"total",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Total"
),
),
(
"status",
models.CharField(
choices=[
("DRAFT", "Draft"),
("ISSUED", "Issued"),
("PAID", "Paid"),
("PARTIALLY_PAID", "Partially Paid"),
("CANCELLED", "Cancelled"),
("OVERDUE", "Overdue"),
],
default="DRAFT",
max_length=20,
verbose_name="Status",
),
),
("notes", models.TextField(blank=True, verbose_name="Notes")),
("history_id", models.AutoField(primary_key=True, serialize=False)),
("history_date", models.DateTimeField(db_index=True)),
("history_change_reason", models.CharField(max_length=100, null=True)),
(
"history_type",
models.CharField(
choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], max_length=1
),
),
(
"appointment",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="appointments.appointment",
verbose_name="Appointment",
),
),
(
"history_user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="+",
to=settings.AUTH_USER_MODEL,
),
),
(
"patient",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="core.patient",
verbose_name="Patient",
),
),
(
"tenant",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="core.tenant",
verbose_name="Tenant",
),
),
(
"payer",
models.ForeignKey(
blank=True,
db_constraint=False,
null=True,
on_delete=django.db.models.deletion.DO_NOTHING,
related_name="+",
to="finance.payer",
verbose_name="Payer",
),
),
],
options={
"verbose_name": "historical Invoice",
"verbose_name_plural": "historical Invoices",
"ordering": ("-history_date", "-history_id"),
"get_latest_by": ("history_date", "history_id"),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name="Payment",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True, verbose_name="Created At")),
("updated_at", models.DateTimeField(auto_now=True, verbose_name="Updated At")),
("payment_date", models.DateTimeField(verbose_name="Payment Date")),
(
"amount",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Amount"
),
),
(
"method",
models.CharField(
choices=[
("CASH", "Cash"),
("CARD", "Credit/Debit Card"),
("BANK_TRANSFER", "Bank Transfer"),
("INSURANCE", "Insurance"),
("CHECK", "Check"),
("OTHER", "Other"),
],
max_length=20,
verbose_name="Payment Method",
),
),
(
"transaction_id",
models.CharField(blank=True, max_length=100, verbose_name="Transaction ID"),
),
(
"reference",
models.CharField(blank=True, max_length=200, verbose_name="Reference"),
),
(
"status",
models.CharField(
choices=[
("PENDING", "Pending"),
("COMPLETED", "Completed"),
("FAILED", "Failed"),
("REFUNDED", "Refunded"),
],
default="PENDING",
max_length=20,
verbose_name="Status",
),
),
("notes", models.TextField(blank=True, verbose_name="Notes")),
(
"invoice",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="payments",
to="finance.invoice",
verbose_name="Invoice",
),
),
(
"processed_by",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="processed_payments",
to=settings.AUTH_USER_MODEL,
verbose_name="Processed By",
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="%(app_label)s_%(class)s_related",
to="core.tenant",
verbose_name="Tenant",
),
),
],
options={
"verbose_name": "Payment",
"verbose_name_plural": "Payments",
"ordering": ["-payment_date"],
},
),
migrations.CreateModel(
name="Service",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True, verbose_name="Created At")),
("updated_at", models.DateTimeField(auto_now=True, verbose_name="Updated At")),
("code", models.CharField(max_length=50, verbose_name="Service Code")),
("name_en", models.CharField(max_length=200, verbose_name="Name (English)")),
(
"name_ar",
models.CharField(blank=True, max_length=200, verbose_name="Name (Arabic)"),
),
(
"base_price",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Base Price"
),
),
(
"duration_minutes",
models.PositiveIntegerField(default=30, verbose_name="Duration (minutes)"),
),
("is_active", models.BooleanField(default=True, verbose_name="Is Active")),
("description", models.TextField(blank=True, verbose_name="Description")),
(
"clinic",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="services",
to="core.clinic",
verbose_name="Clinic",
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="%(app_label)s_%(class)s_related",
to="core.tenant",
verbose_name="Tenant",
),
),
],
options={
"verbose_name": "Service",
"verbose_name_plural": "Services",
"ordering": ["clinic", "name_en"],
},
),
migrations.CreateModel(
name="Package",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True, verbose_name="Created At")),
("updated_at", models.DateTimeField(auto_now=True, verbose_name="Updated At")),
("name_en", models.CharField(max_length=200, verbose_name="Name (English)")),
(
"name_ar",
models.CharField(blank=True, max_length=200, verbose_name="Name (Arabic)"),
),
("total_sessions", models.PositiveIntegerField(verbose_name="Total Sessions")),
(
"price",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Package Price"
),
),
(
"validity_days",
models.PositiveIntegerField(
default=90,
help_text="Number of days the package is valid after purchase",
verbose_name="Validity (days)",
),
),
("is_active", models.BooleanField(default=True, verbose_name="Is Active")),
("description", models.TextField(blank=True, verbose_name="Description")),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="%(app_label)s_%(class)s_related",
to="core.tenant",
verbose_name="Tenant",
),
),
(
"services",
models.ManyToManyField(
related_name="packages", to="finance.service", verbose_name="Services"
),
),
],
options={
"verbose_name": "Package",
"verbose_name_plural": "Packages",
"ordering": ["name_en"],
},
),
migrations.CreateModel(
name="InvoiceLineItem",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"description",
models.CharField(
blank=True, max_length=500, null=True, verbose_name="Description"
),
),
("quantity", models.PositiveIntegerField(default=1, verbose_name="Quantity")),
(
"unit_price",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Unit Price"
),
),
(
"total",
models.DecimalField(
decimal_places=2, default=0.0, max_digits=10, verbose_name="Total"
),
),
(
"invoice",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="line_items",
to="finance.invoice",
verbose_name="Invoice",
),
),
(
"package",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="invoice_line_items",
to="finance.package",
verbose_name="Package",
),
),
(
"service",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="invoice_line_items",
to="finance.service",
verbose_name="Service",
),
),
],
options={
"verbose_name": "Invoice Line Item",
"verbose_name_plural": "Invoice Line Items",
"ordering": ["invoice", "id"],
},
),
migrations.CreateModel(
name="PackagePurchase",
fields=[
(
"id",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created_at", models.DateTimeField(auto_now_add=True, verbose_name="Created At")),
("updated_at", models.DateTimeField(auto_now=True, verbose_name="Updated At")),
("purchase_date", models.DateField(verbose_name="Purchase Date")),
("expiry_date", models.DateField(verbose_name="Expiry Date")),
("total_sessions", models.PositiveIntegerField(verbose_name="Total Sessions")),
(
"sessions_used",
models.PositiveIntegerField(default=0, verbose_name="Sessions Used"),
),
(
"status",
models.CharField(
choices=[
("ACTIVE", "Active"),
("EXPIRED", "Expired"),
("COMPLETED", "Completed"),
("CANCELLED", "Cancelled"),
],
default="ACTIVE",
max_length=20,
verbose_name="Status",
),
),
(
"invoice",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="package_purchases",
to="finance.invoice",
verbose_name="Invoice",
),
),
(
"package",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="purchases",
to="finance.package",
verbose_name="Package",
),
),
(
"patient",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="package_purchases",
to="core.patient",
verbose_name="Patient",
),
),
(
"tenant",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="%(app_label)s_%(class)s_related",
to="core.tenant",
verbose_name="Tenant",
),
),
],
options={
"verbose_name": "Package Purchase",
"verbose_name_plural": "Package Purchases",
"ordering": ["-purchase_date"],
"indexes": [
models.Index(
fields=["patient", "status"], name="finance_pac_patient_be5189_idx"
),
models.Index(
fields=["expiry_date", "status"], name="finance_pac_expiry__2283b7_idx"
),
],
},
),
migrations.AddIndex(
model_name="invoice",
index=models.Index(fields=["invoice_number"], name="finance_inv_invoice_89da8a_idx"),
),
migrations.AddIndex(
model_name="invoice",
index=models.Index(
fields=["patient", "issue_date"], name="finance_inv_patient_909038_idx"
),
),
migrations.AddIndex(
model_name="invoice",
index=models.Index(
fields=["status", "issue_date"], name="finance_inv_status_7e531e_idx"
),
),
migrations.AddIndex(
model_name="invoice",
index=models.Index(
fields=["tenant", "issue_date"], name="finance_inv_tenant__c5242e_idx"
),
),
migrations.AddIndex(
model_name="payment",
index=models.Index(
fields=["invoice", "payment_date"], name="finance_pay_invoice_8fca2f_idx"
),
),
migrations.AddIndex(
model_name="payment",
index=models.Index(
fields=["status", "payment_date"], name="finance_pay_status_549635_idx"
),
),
migrations.AddIndex(
model_name="payment",
index=models.Index(
fields=["tenant", "payment_date"], name="finance_pay_tenant__c6da43_idx"
),
),
migrations.AlterUniqueTogether(
name="service",
unique_together={("tenant", "code")},
),
]