# Generated by Django 4.2.29 on 2026-04-12 22:00

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


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('students', '0002_alter_student_date_of_birth'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('academics', '0003_alter_attendance_date_alter_attendance_synced_at_and_more'),
    ]

    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)),
                ('is_active', models.BooleanField(default=True)),
            ],
            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(blank=True, help_text='Auto-generated if left blank', max_length=150, verbose_name='Fee Structure Name')),
                ('section', models.CharField(choices=[('anglo', 'Anglo Section'), ('bilingual', 'Bilingual Section')], default='anglo', max_length=20, verbose_name='School Section')),
                ('class_group', models.CharField(choices=[('pre_nursery', 'Pre-Nursery (Anglo)'), ('nursery', 'Nursery 1 & 2 (Anglo)'), ('primary_1_5', 'Primary 1–5 (Anglo)'), ('primary_6', 'Primary 6 (Anglo)'), ('maternelle', 'Maternelle / Moyenne & Grande Section (Bilingual)'), ('sil_cm1', 'SIL – CM1 (Bilingual)'), ('cm2', 'CM2 (Bilingual)')], help_text="Select the row from the fee table this structure represents. e.g. 'Primary 1–5 (Anglo)'", max_length=20, verbose_name='Class Group / Fee Tier')),
                ('academic_year', models.CharField(default='2025-2026', help_text='e.g. 2025-2026', max_length=9, verbose_name='Academic Year')),
                ('registration_new', models.DecimalField(decimal_places=0, default=15000, help_text='From fee table: 15,000 XAF for new pupils', max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Registration Fee — New Pupil (XAF)')),
                ('registration_old', models.DecimalField(decimal_places=0, default=10000, help_text='From fee table: 10,000 XAF for returning pupils', max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Registration Fee — Old/Returning Pupil (XAF)')),
                ('total_fees', models.DecimalField(decimal_places=0, help_text="The 'Fees' column in the table — full-year tuition. Must equal installment_1 + installment_2.", max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Total Annual Fees (XAF)')),
                ('installment_1', models.DecimalField(decimal_places=0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='1st Installment (XAF)')),
                ('installment_2', models.DecimalField(decimal_places=0, max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='2nd Installment (XAF)')),
                ('is_active', models.BooleanField(default=True, verbose_name='Active')),
                ('description', 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')),
                ('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='Optionally link to exact class records (e.g. CP-A, CP-B). Leave blank to apply to the whole class group.', related_name='fee_structures', to='academics.schoolclass', verbose_name='Specific Classes')),
            ],
            options={
                'verbose_name': 'Fee Structure',
                'verbose_name_plural': 'Fee Structures',
                'ordering': ['academic_year', 'section', 'class_group'],
            },
        ),
        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')),
                ('invoice_type', models.CharField(choices=[('registration', 'Registration Fee'), ('installment_1', '1st Installment (Tuition)'), ('installment_2', '2nd Installment (Tuition)'), ('item_sale', 'School Item Sale'), ('other', 'Other')], default='installment_1', max_length=20, verbose_name='Invoice Type')),
                ('academic_year', models.CharField(default='2025-2026', max_length=9, verbose_name='Academic Year')),
                ('issue_date', models.DateField(default=django.utils.timezone.now, verbose_name='Issue Date')),
                ('due_date', models.DateField(verbose_name='Due Date')),
                ('total_amount', models.DecimalField(decimal_places=0, max_digits=10, verbose_name='Total Amount (XAF)')),
                ('amount_paid', models.DecimalField(decimal_places=0, default=0, max_digits=10, verbose_name='Amount Paid (XAF)')),
                ('balance', models.DecimalField(decimal_places=0, default=0, max_digits=10, verbose_name='Balance (XAF)')),
                ('status', models.CharField(choices=[('draft', 'Draft'), ('sent', 'Sent'), ('partial', 'Partially Paid'), ('paid', 'Paid'), ('overdue', 'Overdue'), ('cancelled', 'Cancelled')], default='draft', max_length=20, verbose_name='Status')),
                ('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')),
                ('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')),
            ],
            options={
                'verbose_name': 'Invoice',
                'verbose_name_plural': 'Invoices',
                'ordering': ['-issue_date', 'student__last_name'],
            },
        ),
        migrations.CreateModel(
            name='StudentEnrollmentFee',
            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')),
                ('is_new_pupil', models.BooleanField(default=False, help_text='Tick for new admissions (registration = 15,000 XAF). Untick for returning pupils (registration = 10,000 XAF).', verbose_name='New Pupil?')),
                ('registration_fee', models.DecimalField(decimal_places=0, default=0, max_digits=10, verbose_name='Registration Fee Applied (XAF)')),
                ('total_fees', models.DecimalField(decimal_places=0, default=0, max_digits=10, verbose_name='Total Annual Fees (XAF)')),
                ('installment_1_due', models.DateField(blank=True, null=True, verbose_name='1st Installment Due Date')),
                ('installment_2_due', models.DateField(blank=True, null=True, verbose_name='2nd Installment Due Date')),
                ('notes', models.TextField(blank=True, verbose_name='Notes')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True)),
                ('fee_structure', models.ForeignKey(help_text='Select the correct class-group fee tier for this student', on_delete=django.db.models.deletion.PROTECT, related_name='enrollment_fees', to='finance.feestructure', verbose_name='Fee Structure')),
                ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='enrollment_fees', to='students.student', verbose_name='Student')),
            ],
            options={
                'verbose_name': 'Student Enrollment Fee',
                'verbose_name_plural': 'Student Enrollment Fees',
                'ordering': ['-academic_year', 'student__last_name'],
                'unique_together': {('student', 'academic_year')},
            },
        ),
        migrations.CreateModel(
            name='SchoolItemPrice',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('item_type', models.CharField(choices=[('uniform', 'Uniform'), ('sportswear', 'Sportswear'), ('report_card', 'Report Card'), ('pullover', 'Pullover'), ('other', 'Other')], max_length=20, verbose_name='Item Type')),
                ('name', models.CharField(help_text="e.g. 'School Uniform', 'Sportswear Kit'", max_length=100, verbose_name='Item Name')),
                ('price', models.DecimalField(decimal_places=0, max_digits=8, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Selling Price (XAF)')),
                ('academic_year', models.CharField(default='2025-2026', max_length=9, verbose_name='Academic Year')),
                ('is_active', models.BooleanField(default=True, verbose_name='Available for Sale')),
                ('description', models.TextField(blank=True, verbose_name='Description / Notes')),
                ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Last Updated')),
            ],
            options={
                'verbose_name': 'School Item Price',
                'verbose_name_plural': 'School Item Prices',
                'ordering': ['item_type', 'name'],
                'unique_together': {('item_type', 'academic_year')},
            },
        ),
        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(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='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')),
                ('quantity', models.PositiveIntegerField(default=1, verbose_name='Quantity')),
                ('unit_price', models.DecimalField(decimal_places=0, max_digits=10, verbose_name='Unit Price (XAF)')),
                ('discount', models.DecimalField(decimal_places=0, default=0, max_digits=10, verbose_name='Discount (XAF)')),
                ('total', models.DecimalField(decimal_places=0, 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')),
                ('school_item', models.ForeignKey(blank=True, help_text='For uniform / sportswear / report card / pullover sales', null=True, on_delete=django.db.models.deletion.SET_NULL, to='finance.schoolitemprice', verbose_name='School Item')),
            ],
            options={
                'verbose_name': 'Invoice Item',
                'verbose_name_plural': 'Invoice Items',
            },
        ),
        migrations.AddField(
            model_name='invoice',
            name='enrollment_fee',
            field=models.ForeignKey(blank=True, help_text="Link to the student's enrollment fee for this year", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoices', to='finance.studentenrollmentfee', verbose_name='Enrollment Fee Record'),
        ),
        migrations.AddField(
            model_name='invoice',
            name='student',
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invoices', to='students.student', verbose_name='Student'),
        ),
        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)),
                ('start_date', models.DateField()),
                ('end_date', models.DateField()),
                ('total_revenue', models.DecimalField(decimal_places=0, default=0, max_digits=12)),
                ('total_expenses', models.DecimalField(decimal_places=0, default=0, max_digits=12)),
                ('net_profit', models.DecimalField(decimal_places=0, default=0, max_digits=12)),
                ('report_file', models.FileField(blank=True, null=True, upload_to='reports/financial/')),
                ('generated_at', models.DateTimeField(auto_now_add=True, null=True)),
                ('notes', models.TextField(blank=True)),
                ('generated_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
            ],
            options={
                'verbose_name': 'Financial Report',
                'verbose_name_plural': 'Financial Reports',
                'ordering': ['-generated_at'],
            },
        ),
        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=0, max_digits=10, verbose_name='Amount (XAF)')),
                ('expense_date', models.DateField(default=django.utils.timezone.now, verbose_name='Date')),
                ('payment_method', models.CharField(choices=[('cash', 'Cash'), ('mobile_money', 'Mobile Money'), ('bank_transfer', 'Bank Transfer'), ('cheque', 'Cheque')], default='cash', max_length=20)),
                ('receipt_number', models.CharField(blank=True, max_length=50)),
                ('vendor', models.CharField(blank=True, max_length=100, verbose_name='Vendor/Payee')),
                ('notes', models.TextField(blank=True)),
                ('receipt_file', models.FileField(blank=True, null=True, upload_to='expenses/receipts/')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('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)),
                ('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='finance.expensecategory')),
                ('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)),
            ],
            options={
                'verbose_name': 'Expense',
                'verbose_name_plural': 'Expenses',
                'ordering': ['-expense_date'],
            },
        ),
        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)),
                ('value', models.DecimalField(decimal_places=0, max_digits=5, verbose_name='Value')),
                ('applies_to', models.CharField(choices=[('all_fees', 'All Fees'), ('tuition_only', 'Tuition Only'), ('specific_fees', 'Specific Fee Rows')], default='all_fees', max_length=20)),
                ('description', models.TextField(blank=True)),
                ('is_active', models.BooleanField(default=True)),
                ('specific_fees', models.ManyToManyField(blank=True, to='finance.feestructure', verbose_name='Specific Fee Rows')),
            ],
            options={
                'verbose_name': 'Discount',
                'verbose_name_plural': 'Discounts',
            },
        ),
        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')),
                ('reason', models.CharField(blank=True, max_length=200, verbose_name='Reason')),
                ('created_at', models.DateTimeField(auto_now_add=True, null=True)),
                ('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',
                'unique_together': {('student', 'discount', 'academic_year')},
            },
        ),
        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=0, max_digits=10, validators=[django.core.validators.MinValueValidator(1)], verbose_name='Amount (XAF)')),
                ('payment_method', models.CharField(choices=[('cash', 'Cash'), ('mobile_money', 'Mobile Money (MTN / Orange)'), ('bank_transfer', 'Bank Transfer'), ('cheque', 'Cheque'), ('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')], 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'],
                'indexes': [models.Index(fields=['payment_number'], name='finance_pay_payment_bb9d71_idx'), models.Index(fields=['invoice', 'status'], name='finance_pay_invoice_80fc36_idx'), models.Index(fields=['payment_date'], name='finance_pay_payment_72f761_idx'), models.Index(fields=['student'], name='finance_pay_student_14b4c3_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'], name='finance_inv_student_b76730_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='feestructure',
            index=models.Index(fields=['academic_year', 'section', 'class_group'], name='finance_fee_academi_9d3ca9_idx'),
        ),
        migrations.AddIndex(
            model_name='feestructure',
            index=models.Index(fields=['is_active'], name='finance_fee_is_acti_595955_idx'),
        ),
        migrations.AlterUniqueTogether(
            name='feestructure',
            unique_together={('section', 'class_group', 'academic_year')},
        ),
    ]
