# Generated by Django 6.0 on 2026-03-04 23:59

import django.core.validators
import django.db.models.deletion
import django.utils.timezone
import finance.utils
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('academics', '0001_initial'),
        ('students', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='ExpenseCategory',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=100, unique=True, verbose_name='Category Name')),
                ('name_fr', models.CharField(blank=True, max_length=100, verbose_name='Category Name (French)')),
                ('description', models.TextField(blank=True, verbose_name='Description')),
                ('is_active', models.BooleanField(default=True, verbose_name='Active')),
            ],
            options={
                'verbose_name': 'Expense Category',
                'verbose_name_plural': 'Expense Categories',
                'ordering': ['name'],
            },
        ),
        migrations.CreateModel(
            name='FeeStructure',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=100, verbose_name='Fee Name')),
                ('name_fr', models.CharField(blank=True, max_length=100, verbose_name='Fee Name (French)')),
                ('fee_type', models.CharField(choices=[('tuition', 'Tuition Fee'), ('registration', 'Registration Fee'), ('pta', 'PTA Fee'), ('uniform', 'Uniform Fee'), ('books', 'Books & Materials'), ('exam', 'Examination Fee'), ('sports', 'Sports Fee'), ('transport', 'Transportation Fee'), ('lunch', 'Lunch Fee'), ('development', 'Development Levy'), ('insurance', 'School Insurance'), ('activity', 'Extra-curricular Activity'), ('other', 'Other Fee')], max_length=20, verbose_name='Fee Type')),
                ('amount', models.DecimalField(decimal_places=2, help_text='Amount in Central African CFA Franc', max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Amount (XAF)')),
                ('payment_frequency', models.CharField(choices=[('once', 'One-time (per year)'), ('termly', 'Per Term'), ('monthly', 'Monthly'), ('weekly', 'Weekly'), ('daily', 'Daily')], default='termly', max_length=20, verbose_name='Payment Frequency')),
                ('class_level', models.CharField(choices=[('all', 'All Classes'), ('nursery', 'Nursery Section'), ('primary', 'Primary Section'), ('specific', 'Specific Classes')], default='all', max_length=20, verbose_name='Class Level')),
                ('is_mandatory', models.BooleanField(default=True, help_text='Is this fee mandatory for all students?', verbose_name='Mandatory Fee')),
                ('academic_year', models.CharField(default='2025-2026', help_text='e.g., 2025-2026', max_length=9, verbose_name='Academic Year')),
                ('term', models.PositiveSmallIntegerField(choices=[(1, 'Term 1'), (2, 'Term 2'), (3, 'Term 3'), (0, 'All Terms')], default=0, help_text='0 = All Terms, 1 = Term 1 only, etc.', verbose_name='Applicable Term')),
                ('description', models.TextField(blank=True, verbose_name='Description')),
                ('description_fr', models.TextField(blank=True, verbose_name='Description (French)')),
                ('is_active', models.BooleanField(default=True, help_text='Is this fee structure currently active?', verbose_name='Active')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')),
                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='fee_structures_created', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('specific_classes', models.ManyToManyField(blank=True, help_text="Select classes if 'Specific Classes' is chosen above", to='academics.schoolclass', verbose_name='Specific Classes')),
            ],
            options={
                'verbose_name': 'Fee Structure',
                'verbose_name_plural': 'Fee Structures',
                'ordering': ['academic_year', 'fee_type', 'name'],
            },
        ),
        migrations.CreateModel(
            name='Discount',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=100, verbose_name='Discount Name')),
                ('name_fr', models.CharField(blank=True, max_length=100, verbose_name='Discount Name (French)')),
                ('discount_type', models.CharField(choices=[('percentage', 'Percentage (%)'), ('fixed', 'Fixed Amount (XAF)')], default='percentage', max_length=20, verbose_name='Discount Type')),
                ('value', models.DecimalField(decimal_places=2, help_text='Percentage or fixed amount', max_digits=5, verbose_name='Discount Value')),
                ('applies_to', models.CharField(choices=[('all_fees', 'All Fees'), ('tuition_only', 'Tuition Only'), ('specific_fees', 'Specific Fees')], default='all_fees', max_length=20, verbose_name='Applies To')),
                ('description', models.TextField(blank=True, verbose_name='Description')),
                ('is_active', models.BooleanField(default=True, verbose_name='Active')),
                ('specific_fees', models.ManyToManyField(blank=True, to='finance.feestructure', verbose_name='Specific Fees')),
            ],
            options={
                'verbose_name': 'Discount',
                'verbose_name_plural': 'Discounts',
            },
        ),
        migrations.CreateModel(
            name='FinancialReport',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=200, verbose_name='Report Title')),
                ('report_type', models.CharField(choices=[('daily', 'Daily Report'), ('weekly', 'Weekly Report'), ('monthly', 'Monthly Report'), ('termly', 'Termly Report'), ('annual', 'Annual Report'), ('custom', 'Custom Date Range')], max_length=20, verbose_name='Report Type')),
                ('start_date', models.DateField(verbose_name='Start Date')),
                ('end_date', models.DateField(verbose_name='End Date')),
                ('total_revenue', models.DecimalField(decimal_places=2, default=0, max_digits=12, verbose_name='Total Revenue')),
                ('total_expenses', models.DecimalField(decimal_places=2, default=0, max_digits=12, verbose_name='Total Expenses')),
                ('net_profit', models.DecimalField(decimal_places=2, default=0, max_digits=12, verbose_name='Net Profit/Loss')),
                ('report_file', models.FileField(blank=True, null=True, upload_to='reports/financial/', verbose_name='Report File')),
                ('generated_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Generated At')),
                ('notes', models.TextField(blank=True, verbose_name='Notes')),
                ('generated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Generated By')),
            ],
            options={
                'verbose_name': 'Financial Report',
                'verbose_name_plural': 'Financial Reports',
                'ordering': ['-generated_at'],
            },
        ),
        migrations.CreateModel(
            name='Invoice',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('invoice_number', models.CharField(default=finance.utils.generate_invoice_number, max_length=20, unique=True, verbose_name='Invoice Number')),
                ('academic_year', models.CharField(default='2025-2026', max_length=9, verbose_name='Academic Year')),
                ('term', models.PositiveSmallIntegerField(choices=[(1, 'Term 1'), (2, 'Term 2'), (3, 'Term 3')], verbose_name='Term')),
                ('issue_date', models.DateField(default=django.utils.timezone.now, verbose_name='Issue Date')),
                ('due_date', models.DateField(verbose_name='Due Date')),
                ('subtotal', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Subtotal (XAF)')),
                ('discount', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Discount (XAF)')),
                ('discount_reason', models.CharField(blank=True, max_length=200, verbose_name='Discount Reason')),
                ('total_amount', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Total Amount (XAF)')),
                ('amount_paid', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Amount Paid (XAF)')),
                ('balance', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Balance (XAF)')),
                ('status', models.CharField(choices=[('draft', 'Draft'), ('sent', 'Sent'), ('partial', 'Partially Paid'), ('paid', 'Paid'), ('overdue', 'Overdue'), ('cancelled', 'Cancelled'), ('void', 'Void')], default='draft', max_length=20, verbose_name='Status')),
                ('notes', models.TextField(blank=True, verbose_name='Notes')),
                ('notes_fr', models.TextField(blank=True, verbose_name='Notes (French)')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')),
                ('last_reminder_sent', models.DateField(blank=True, null=True, verbose_name='Last Reminder Sent')),
                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoices_created', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invoices', to='students.student', verbose_name='Student')),
            ],
            options={
                'verbose_name': 'Invoice',
                'verbose_name_plural': 'Invoices',
                'ordering': ['-issue_date', 'student__last_name'],
            },
        ),
        migrations.CreateModel(
            name='InvoiceItem',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('description', models.CharField(max_length=200, verbose_name='Description')),
                ('description_fr', models.CharField(blank=True, max_length=200, verbose_name='Description (French)')),
                ('quantity', models.PositiveIntegerField(default=1, verbose_name='Quantity')),
                ('unit_price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Unit Price (XAF)')),
                ('discount', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Discount (XAF)')),
                ('total', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Total (XAF)')),
                ('fee_structure', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='finance.feestructure', verbose_name='Fee Structure')),
                ('invoice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='finance.invoice', verbose_name='Invoice')),
            ],
            options={
                'verbose_name': 'Invoice Item',
                'verbose_name_plural': 'Invoice Items',
            },
        ),
        migrations.CreateModel(
            name='Payment',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('payment_number', models.CharField(blank=True, max_length=20, unique=True, verbose_name='Payment Number')),
                ('amount', models.DecimalField(decimal_places=2, max_digits=10, validators=[django.core.validators.MinValueValidator(1)], verbose_name='Amount (XAF)')),
                ('payment_method', models.CharField(choices=[('cash', 'Cash'), ('bank_transfer', 'Bank Transfer'), ('mobile_money', 'Mobile Money'), ('check', 'Cheque'), ('card', 'Credit/Debit Card'), ('other', 'Other')], max_length=20, verbose_name='Payment Method')),
                ('payment_date', models.DateField(default=django.utils.timezone.now, verbose_name='Payment Date')),
                ('mobile_money_provider', models.CharField(blank=True, choices=[('mtn', 'MTN Mobile Money'), ('orange', 'Orange Money'), ('express_union', 'Express Union'), ('other', 'Other Provider')], max_length=20, verbose_name='Mobile Money Provider')),
                ('mobile_money_number', models.CharField(blank=True, max_length=20, verbose_name='Mobile Money Number')),
                ('transaction_id', models.CharField(blank=True, max_length=100, verbose_name='Transaction ID/Reference')),
                ('bank_name', models.CharField(blank=True, max_length=100, verbose_name='Bank Name')),
                ('cheque_number', models.CharField(blank=True, max_length=50, verbose_name='Cheque Number')),
                ('status', models.CharField(choices=[('pending', 'Pending'), ('completed', 'Completed'), ('failed', 'Failed'), ('cancelled', 'Cancelled'), ('refunded', 'Refunded')], default='pending', max_length=20, verbose_name='Status')),
                ('receipt_number', models.CharField(blank=True, max_length=50, verbose_name='Receipt Number')),
                ('receipt_issued', models.BooleanField(default=False, verbose_name='Receipt Issued')),
                ('receipt_issued_date', models.DateField(blank=True, null=True, verbose_name='Receipt Issued Date')),
                ('notes', models.TextField(blank=True, verbose_name='Notes')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')),
                ('invoice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='payments', to='finance.invoice', verbose_name='Invoice')),
                ('received_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='payments_received', to=settings.AUTH_USER_MODEL, verbose_name='Received By')),
                ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='payments', to='students.student', verbose_name='Student')),
            ],
            options={
                'verbose_name': 'Payment',
                'verbose_name_plural': 'Payments',
                'ordering': ['-payment_date', '-created_at'],
            },
        ),
        migrations.CreateModel(
            name='PaymentReminder',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('reminder_type', models.CharField(choices=[('sms', 'SMS'), ('email', 'Email'), ('whatsapp', 'WhatsApp'), ('call', 'Phone Call'), ('letter', 'Physical Letter')], max_length=20, verbose_name='Reminder Type')),
                ('sent_to', models.CharField(help_text='Phone number or email address', max_length=100, verbose_name='Sent To')),
                ('sent_date', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Sent Date')),
                ('response', models.TextField(blank=True, verbose_name='Response')),
                ('invoice', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reminders', to='finance.invoice', verbose_name='Invoice')),
                ('sent_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Sent By')),
            ],
            options={
                'verbose_name': 'Payment Reminder',
                'verbose_name_plural': 'Payment Reminders',
                'ordering': ['-sent_date'],
            },
        ),
        migrations.CreateModel(
            name='StudentDiscount',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('academic_year', models.CharField(default='2025-2026', max_length=9, verbose_name='Academic Year')),
                ('term', models.PositiveSmallIntegerField(choices=[(1, 'Term 1'), (2, 'Term 2'), (3, 'Term 3'), (0, 'All Terms')], default=0, verbose_name='Applicable Term')),
                ('reason', models.CharField(blank=True, max_length=200, verbose_name='Reason')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('approved_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='approved_discounts', to=settings.AUTH_USER_MODEL, verbose_name='Approved By')),
                ('discount', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='finance.discount', verbose_name='Discount')),
                ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='discounts', to='students.student', verbose_name='Student')),
            ],
            options={
                'verbose_name': 'Student Discount',
                'verbose_name_plural': 'Student Discounts',
            },
        ),
        migrations.CreateModel(
            name='Expense',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('expense_number', models.CharField(blank=True, max_length=20, unique=True, verbose_name='Expense Number')),
                ('description', models.CharField(max_length=200, verbose_name='Description')),
                ('amount', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Amount (XAF)')),
                ('expense_date', models.DateField(default=django.utils.timezone.now, verbose_name='Expense Date')),
                ('payment_method', models.CharField(choices=[('cash', 'Cash'), ('bank_transfer', 'Bank Transfer'), ('mobile_money', 'Mobile Money'), ('check', 'Cheque')], default='cash', max_length=20, verbose_name='Payment Method')),
                ('receipt_number', models.CharField(blank=True, max_length=50, verbose_name='Receipt Number')),
                ('vendor', models.CharField(blank=True, max_length=100, verbose_name='Vendor/Payee')),
                ('notes', models.TextField(blank=True, verbose_name='Notes')),
                ('receipt_file', models.FileField(blank=True, null=True, upload_to='expenses/receipts/', verbose_name='Receipt File')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Created At')),
                ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')),
                ('approved_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='approved_expenses', to=settings.AUTH_USER_MODEL, verbose_name='Approved By')),
                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expenses_created', to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
                ('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='finance.expensecategory', verbose_name='Category')),
            ],
            options={
                'verbose_name': 'Expense',
                'verbose_name_plural': 'Expenses',
                'ordering': ['-expense_date'],
                'indexes': [models.Index(fields=['expense_number'], name='finance_exp_expense_d6be0d_idx'), models.Index(fields=['expense_date'], name='finance_exp_expense_a60cc7_idx'), models.Index(fields=['category'], name='finance_exp_categor_e43046_idx')],
            },
        ),
        migrations.AddIndex(
            model_name='feestructure',
            index=models.Index(fields=['academic_year', 'fee_type'], name='finance_fee_academi_4ab364_idx'),
        ),
        migrations.AddIndex(
            model_name='feestructure',
            index=models.Index(fields=['is_active'], name='finance_fee_is_acti_595955_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=['student', 'academic_year', 'term'], name='finance_inv_student_2629d4_idx'),
        ),
        migrations.AddIndex(
            model_name='invoice',
            index=models.Index(fields=['status'], name='finance_inv_status_d9b47e_idx'),
        ),
        migrations.AddIndex(
            model_name='invoice',
            index=models.Index(fields=['due_date'], name='finance_inv_due_dat_b93853_idx'),
        ),
        migrations.AddIndex(
            model_name='payment',
            index=models.Index(fields=['payment_number'], name='finance_pay_payment_bb9d71_idx'),
        ),
        migrations.AddIndex(
            model_name='payment',
            index=models.Index(fields=['invoice', 'status'], name='finance_pay_invoice_80fc36_idx'),
        ),
        migrations.AddIndex(
            model_name='payment',
            index=models.Index(fields=['payment_date'], name='finance_pay_payment_72f761_idx'),
        ),
        migrations.AddIndex(
            model_name='payment',
            index=models.Index(fields=['student'], name='finance_pay_student_14b4c3_idx'),
        ),
        migrations.AlterUniqueTogether(
            name='studentdiscount',
            unique_together={('student', 'discount', 'academic_year', 'term')},
        ),
    ]
