# Generated by Django 5.2.17 on 2026-09-03 13:18

import django.db.models.deletion
import uuid
from decimal import Decimal
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('customers', '0004_notificationpreference_email_enabled_and_more'),
        ('tenancy', '0004_staffprofile'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Account',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('code', models.CharField(max_length=50)),
                ('name', models.CharField(max_length=200)),
                ('category', models.CharField(choices=[('ASSET', 'Asset'), ('LIABILITY', 'Liability'), ('EQUITY', 'Equity'), ('REVENUE', 'Revenue'), ('EXPENSE', 'Expense')], max_length=30)),
                ('account_type', models.CharField(choices=[('CURRENT_ASSET', 'Current Asset'), ('NON_CURRENT_ASSET', 'Non-Current Asset'), ('CURRENT_LIABILITY', 'Current Liability'), ('LONG_TERM_LIABILITY', 'Long-Term Liability'), ('EQUITY', 'Equity'), ('OPERATING_REVENUE', 'Operating Revenue'), ('NON_OPERATING_REVENUE', 'Non-Operating Revenue'), ('DIRECT_EXPENSE', 'Direct Expense'), ('OPERATING_EXPENSE', 'Operating Expense'), ('ADMINISTRATIVE_EXPENSE', 'Administrative Expense')], max_length=40)),
                ('description', models.TextField(blank=True)),
                ('is_system', models.BooleanField(default=False, help_text='System accounts (e.g. Accounts Receivable, Cash) cannot be deleted or deactivated.')),
                ('is_active', models.BooleanField(default=True)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
                ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='children', to='accounting.account')),
            ],
            options={
                'db_table': 'accounting_account',
                'ordering': ['code'],
            },
        ),
        migrations.CreateModel(
            name='FinancialPeriod',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('name', models.CharField(max_length=100)),
                ('start_date', models.DateField()),
                ('end_date', models.DateField()),
                ('is_closed', models.BooleanField(default=False)),
                ('closed_at', models.DateTimeField(blank=True, null=True)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('closed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='closed_financial_periods', to=settings.AUTH_USER_MODEL)),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
            ],
            options={
                'db_table': 'accounting_financial_period',
                'ordering': ['-start_date'],
            },
        ),
        migrations.CreateModel(
            name='JournalEntry',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('entry_number', models.CharField(max_length=100)),
                ('date', models.DateField()),
                ('narration', models.TextField()),
                ('reference_type', models.CharField(choices=[('MANUAL', 'Manual Journal Entry'), ('INVOICE', 'Customer Invoice'), ('PAYMENT', 'Customer Payment'), ('PAYMENT_REVERSAL', 'Payment Reversal'), ('INVOICE_CANCEL', 'Invoice Cancellation'), ('EXPENSE', 'Operational Expense'), ('INCOME', 'Direct Income'), ('TRANSFER', 'Cash / Bank Transfer'), ('DEALER_ACCRUAL', 'Dealer Commission Accrual'), ('DEALER_SETTLEMENT', 'Dealer Payout Settlement')], default='MANUAL', max_length=40)),
                ('reference_id', models.CharField(blank=True, max_length=255)),
                ('status', models.CharField(choices=[('DRAFT', 'Draft'), ('POSTED', 'Posted'), ('REVERSED', 'Reversed')], default='POSTED', max_length=30)),
                ('posted_at', models.DateTimeField(blank=True, null=True)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_journal_entries', to=settings.AUTH_USER_MODEL)),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
                ('period', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='journal_entries', to='accounting.financialperiod')),
                ('posted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='posted_journal_entries', to=settings.AUTH_USER_MODEL)),
                ('reversed_entry', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reversals', to='accounting.journalentry')),
            ],
            options={
                'db_table': 'accounting_journal_entry',
                'ordering': ['-date', '-created_at'],
            },
        ),
        migrations.CreateModel(
            name='FundTransfer',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('transfer_number', models.CharField(max_length=100)),
                ('amount', models.DecimalField(decimal_places=2, max_digits=12)),
                ('date', models.DateField()),
                ('reference', models.CharField(blank=True, max_length=150)),
                ('description', models.TextField(blank=True)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('from_account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='transfers_out', to='accounting.account')),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
                ('to_account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='transfers_in', to='accounting.account')),
                ('transferred_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transferred_funds', to=settings.AUTH_USER_MODEL)),
                ('journal_entry', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='fund_transfer_record', to='accounting.journalentry')),
            ],
            options={
                'db_table': 'accounting_fund_transfer',
                'ordering': ['-date', '-created_at'],
            },
        ),
        migrations.CreateModel(
            name='Expense',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('expense_number', models.CharField(max_length=100)),
                ('amount', models.DecimalField(decimal_places=2, max_digits=12)),
                ('date', models.DateField()),
                ('payee', models.CharField(blank=True, max_length=200)),
                ('category', models.CharField(blank=True, max_length=100)),
                ('reference', models.CharField(blank=True, max_length=150)),
                ('description', models.TextField(blank=True)),
                ('receipt_file', models.FileField(blank=True, null=True, upload_to='expenses/%Y/%m/')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('expense_account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='accounting.account')),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
                ('payment_account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='expense_payments', to='accounting.account')),
                ('recorded_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='recorded_expenses', to=settings.AUTH_USER_MODEL)),
                ('journal_entry', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expense_record', to='accounting.journalentry')),
            ],
            options={
                'db_table': 'accounting_expense',
                'ordering': ['-date', '-created_at'],
            },
        ),
        migrations.CreateModel(
            name='DirectIncome',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('income_number', models.CharField(max_length=100)),
                ('amount', models.DecimalField(decimal_places=2, max_digits=12)),
                ('date', models.DateField()),
                ('received_from', models.CharField(blank=True, max_length=200)),
                ('reference', models.CharField(blank=True, max_length=150)),
                ('description', models.TextField(blank=True)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('deposit_account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='income_deposits', to='accounting.account')),
                ('income_account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='direct_incomes', to='accounting.account')),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
                ('recorded_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='recorded_incomes', to=settings.AUTH_USER_MODEL)),
                ('journal_entry', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='direct_income_record', to='accounting.journalentry')),
            ],
            options={
                'db_table': 'accounting_direct_income',
                'ordering': ['-date', '-created_at'],
            },
        ),
        migrations.CreateModel(
            name='DealerSettlement',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('settlement_number', models.CharField(max_length=100)),
                ('amount', models.DecimalField(decimal_places=2, max_digits=12)),
                ('period_start', models.DateField()),
                ('period_end', models.DateField()),
                ('settlement_date', models.DateField()),
                ('notes', models.TextField(blank=True)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_dealer_settlements', to=settings.AUTH_USER_MODEL)),
                ('dealer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='settlements', to='customers.dealer')),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
                ('payment_account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='dealer_settlements', to='accounting.account')),
                ('journal_entry', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dealer_settlement_record', to='accounting.journalentry')),
            ],
            options={
                'db_table': 'accounting_dealer_settlement',
                'ordering': ['-settlement_date', '-created_at'],
            },
        ),
        migrations.CreateModel(
            name='JournalLine',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('description', models.CharField(blank=True, max_length=255)),
                ('debit', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=14)),
                ('credit', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=14)),
                ('line_order', models.PositiveIntegerField(default=0)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='journal_lines', to='accounting.account')),
                ('journal_entry', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lines', to='accounting.journalentry')),
                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_records', to='tenancy.organization')),
            ],
            options={
                'db_table': 'accounting_journal_line',
                'ordering': ['line_order', 'created_at'],
            },
        ),
        migrations.AddIndex(
            model_name='account',
            index=models.Index(fields=['organization', 'category'], name='acc_org_cat_idx'),
        ),
        migrations.AddIndex(
            model_name='account',
            index=models.Index(fields=['organization', 'account_type'], name='acc_org_type_idx'),
        ),
        migrations.AddIndex(
            model_name='account',
            index=models.Index(fields=['organization', 'is_active'], name='acc_org_active_idx'),
        ),
        migrations.AddConstraint(
            model_name='account',
            constraint=models.UniqueConstraint(fields=('organization', 'code'), name='unique_account_code_per_org'),
        ),
        migrations.AddIndex(
            model_name='financialperiod',
            index=models.Index(fields=['organization', 'is_closed'], name='period_org_closed_idx'),
        ),
        migrations.AddIndex(
            model_name='financialperiod',
            index=models.Index(fields=['organization', 'start_date', 'end_date'], name='period_org_dates_idx'),
        ),
        migrations.AddConstraint(
            model_name='financialperiod',
            constraint=models.UniqueConstraint(fields=('organization', 'name'), name='unique_period_name_per_org'),
        ),
        migrations.AddConstraint(
            model_name='financialperiod',
            constraint=models.CheckConstraint(condition=models.Q(('end_date__gte', models.F('start_date'))), name='period_end_gte_start'),
        ),
        migrations.AddIndex(
            model_name='journalentry',
            index=models.Index(fields=['organization', 'date'], name='je_org_date_idx'),
        ),
        migrations.AddIndex(
            model_name='journalentry',
            index=models.Index(fields=['organization', 'status'], name='je_org_status_idx'),
        ),
        migrations.AddIndex(
            model_name='journalentry',
            index=models.Index(fields=['organization', 'reference_type', 'reference_id'], name='je_org_ref_idx'),
        ),
        migrations.AddConstraint(
            model_name='journalentry',
            constraint=models.UniqueConstraint(fields=('organization', 'entry_number'), name='unique_journal_entry_number_per_org'),
        ),
        migrations.AddConstraint(
            model_name='fundtransfer',
            constraint=models.UniqueConstraint(fields=('organization', 'transfer_number'), name='unique_transfer_number_per_org'),
        ),
        migrations.AddConstraint(
            model_name='fundtransfer',
            constraint=models.CheckConstraint(condition=models.Q(('amount__gt', 0)), name='transfer_amount_gt_zero'),
        ),
        migrations.AddIndex(
            model_name='expense',
            index=models.Index(fields=['organization', 'date'], name='exp_org_date_idx'),
        ),
        migrations.AddIndex(
            model_name='expense',
            index=models.Index(fields=['organization', 'category'], name='exp_org_cat_idx'),
        ),
        migrations.AddConstraint(
            model_name='expense',
            constraint=models.UniqueConstraint(fields=('organization', 'expense_number'), name='unique_expense_number_per_org'),
        ),
        migrations.AddConstraint(
            model_name='expense',
            constraint=models.CheckConstraint(condition=models.Q(('amount__gt', 0)), name='expense_amount_gt_zero'),
        ),
        migrations.AddIndex(
            model_name='directincome',
            index=models.Index(fields=['organization', 'date'], name='inc_org_date_idx'),
        ),
        migrations.AddConstraint(
            model_name='directincome',
            constraint=models.UniqueConstraint(fields=('organization', 'income_number'), name='unique_income_number_per_org'),
        ),
        migrations.AddConstraint(
            model_name='directincome',
            constraint=models.CheckConstraint(condition=models.Q(('amount__gt', 0)), name='income_amount_gt_zero'),
        ),
        migrations.AddConstraint(
            model_name='dealersettlement',
            constraint=models.UniqueConstraint(fields=('organization', 'settlement_number'), name='unique_dealer_settlement_number_per_org'),
        ),
        migrations.AddConstraint(
            model_name='dealersettlement',
            constraint=models.CheckConstraint(condition=models.Q(('amount__gt', 0)), name='settlement_amount_gt_zero'),
        ),
        migrations.AddIndex(
            model_name='journalline',
            index=models.Index(fields=['organization', 'account'], name='jline_org_acc_idx'),
        ),
        migrations.AddIndex(
            model_name='journalline',
            index=models.Index(fields=['organization', 'journal_entry'], name='jline_org_entry_idx'),
        ),
        migrations.AddConstraint(
            model_name='journalline',
            constraint=models.CheckConstraint(condition=models.Q(('debit__gte', 0)), name='journal_line_debit_gte_zero'),
        ),
        migrations.AddConstraint(
            model_name='journalline',
            constraint=models.CheckConstraint(condition=models.Q(('credit__gte', 0)), name='journal_line_credit_gte_zero'),
        ),
        migrations.AddConstraint(
            model_name='journalline',
            constraint=models.CheckConstraint(condition=models.Q(('debit__gt', 0), ('credit__gt', 0), _connector='OR'), name='journal_line_has_debit_or_credit'),
        ),
    ]
