# Generated by Django 5.0.3 on 2024-04-15 09:05

import django.db.models.deletion
import django_fsm
import wbaccounting.models.entry_accounting_information
from django.conf import settings
from django.db import migrations, models
from django.db.models import Max
from django.utils.html import strip_tags


def swap_net_and_gross(apps, schema_editor):
    # We are using the wrong notion for net and gross, we need to swap them
    BookingEntry = apps.get_model("wbaccounting", "BookingEntry")
    for bookingentry in BookingEntry.objects.all():
        bookingentry.net_value, bookingentry.gross_value = bookingentry.gross_value, bookingentry.net_value
        bookingentry.save()


def migrate_dates(apps, schema_editor):
    # We are migrating from/to date from fields to parameters, as they are getting removed
    # Also we are setting the reference date to to date, as it is the last date of the accounting period
    BookingEntry = apps.get_model("wbaccounting", "BookingEntry")
    for bookingentry in BookingEntry.objects.filter(from_date__isnull=False, to_date__isnull=False):
        bookingentry.parameters = {
            "from_date": bookingentry.from_date.strftime("%d.%m.%Y"),
            "to_date": bookingentry.to_date.strftime("%d.%m.%Y"),
        }
        bookingentry.reference_date = bookingentry.to_date
        bookingentry.save()

    # As the reference date is set for the bookings entries, the
    Invoice = apps.get_model("wbaccounting", "Invoice")
    for invoice in Invoice.objects.filter(booking_entries__isnull=False):
        invoice.reference_date = invoice.booking_entries.aggregate(mv=Max("reference_date")).get("mv")
        invoice.save()


def strip_html_from_subject(apps, schema_editor):
    EntryAccountingInformation = apps.get_model("wbaccounting", "EntryAccountingInformation")

    for eai in EntryAccountingInformation.objects.all():
        eai.email_subject = strip_tags(eai.email_subject)
        eai.save()


def save_models(apps, schema_editor):
    from wbaccounting.models import BookingEntry

    for bookingentry in BookingEntry.objects.all():
        bookingentry.save()


class Migration(migrations.Migration):
    dependencies = [
        ("currency", "0001_initial"),
        ("directory", "0007_alter_bankingcontact_options"),
        ("wbaccounting", "0008_alter_invoice_options"),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name="InvoiceType",
            fields=[
                ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("name", models.CharField(max_length=100, unique=True, verbose_name="Name")),
                ("processor", models.CharField(blank=True, max_length=128, null=True, verbose_name="Processor")),
            ],
            options={
                "verbose_name": "Invoice Type",
                "verbose_name_plural": "Invoice Types",
            },
        ),
        migrations.AlterModelOptions(
            name="bookingentry",
            options={"verbose_name": "Booking", "verbose_name_plural": "Bookings"},
        ),
        migrations.AlterModelOptions(
            name="entryaccountinginformation",
            options={"verbose_name": "Accounting Information", "verbose_name_plural": "Accounting Information"},
        ),
        migrations.AlterModelOptions(
            name="invoice",
            options={
                "permissions": (
                    ("can_generate_invoice", "Can Generate Invoice"),
                    ("administrate_invoice", "Can administer Invoice"),
                ),
                "verbose_name": "Invoice",
                "verbose_name_plural": "Invoices",
            },
        ),
        migrations.RemoveField(
            model_name="bookingentry",
            name="accrual_date",
        ),
        migrations.RemoveField(
            model_name="bookingentry",
            name="calculated_value",
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="parameters",
            field=models.JSONField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="reference_date",
            field=models.DateField(blank=True, null=True, verbose_name="Reference Date"),
        ),
        migrations.AddField(
            model_name="invoice",
            name="reference_date",
            field=models.DateField(blank=True, null=True, verbose_name="Reference Date"),
        ),
        migrations.RunSQL(sql="SET CONSTRAINTS ALL IMMEDIATE;"),
        migrations.RunPython(
            swap_net_and_gross,
            reverse_code=migrations.RunPython.noop,
        ),
        migrations.RunPython(
            migrate_dates,
            reverse_code=migrations.RunPython.noop,
        ),
        migrations.RunSQL(sql="SET CONSTRAINTS ALL DEFERRED;"),
        migrations.RemoveField(
            model_name="bookingentry",
            name="from_date",
        ),
        migrations.RemoveField(
            model_name="bookingentry",
            name="to_date",
        ),
        migrations.RemoveField(
            model_name="bookingentry",
            name="main_booking_entry",
        ),
        migrations.RemoveField(
            model_name="bookingentry",
            name="related_data",
        ),
        migrations.RemoveField(
            model_name="bookingentry",
            name="resolved",
        ),
        migrations.RemoveField(
            model_name="entryaccountinginformation",
            name="label_mapping",
        ),
        migrations.RemoveField(
            model_name="entryaccountinginformation",
            name="social_charges",
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="backlinks",
            field=models.JSONField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="due_date",
            field=models.DateField(blank=True, null=True, verbose_name="Due Date"),
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="generator",
            field=models.CharField(blank=True, max_length=256, null=True),
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="invoice_fx_rate",
            field=models.DecimalField(
                blank=True, decimal_places=6, max_digits=20, null=True, verbose_name="Invoice FX Rate"
            ),
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="invoice_gross_value",
            field=models.DecimalField(
                blank=True, decimal_places=4, max_digits=16, null=True, verbose_name="Invoice Gross Value"
            ),
        ),
        migrations.AddField(
            model_name="bookingentry",
            name="invoice_net_value",
            field=models.DecimalField(
                blank=True, decimal_places=4, max_digits=16, null=True, verbose_name="Invoice Net Value"
            ),
        ),
        migrations.AddField(
            model_name="entryaccountinginformation",
            name="booking_entry_generator",
            field=models.CharField(blank=True, max_length=256, null=True),
        ),
        migrations.AddField(
            model_name="entryaccountinginformation",
            name="counterparty_is_private",
            field=models.BooleanField(
                default=False,
                help_text="Hides all of the counterparty's invoices from non-eligible users",
                verbose_name="Counterparty Is Private",
            ),
        ),
        migrations.AddField(
            model_name="entryaccountinginformation",
            name="exempt_users",
            field=models.ManyToManyField(
                blank=True,
                help_text="Exclusion list of users who are able to see private invoices for the counterparty",
                related_name="private_accounting_information",
                to=settings.AUTH_USER_MODEL,
                verbose_name="Exempt Users",
            ),
        ),
        migrations.AddField(
            model_name="entryaccountinginformation",
            name="send_mail",
            field=models.BooleanField(default=True, verbose_name="Send Mail"),
        ),
        migrations.AddField(
            model_name="invoice",
            name="backlinks",
            field=models.JSONField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="invoice",
            name="gross_value",
            field=models.DecimalField(
                blank=True, decimal_places=4, max_digits=16, null=True, verbose_name="Gross Value"
            ),
        ),
        migrations.AddField(
            model_name="invoice",
            name="net_value",
            field=models.DecimalField(
                blank=True, decimal_places=4, max_digits=16, null=True, verbose_name="Net Value"
            ),
        ),
        migrations.AlterField(
            model_name="entryaccountinginformation",
            name="default_currency",
            field=models.ForeignKey(
                blank=True,
                default=wbaccounting.models.entry_accounting_information.default_currency,
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="entry_accounting_informations",
                to="currency.currency",
                verbose_name="Default Currency",
            ),
        ),
        migrations.AlterField(
            model_name="entryaccountinginformation",
            name="email_body",
            field=models.TextField(
                default=wbaccounting.models.entry_accounting_information.default_email_body, verbose_name="Body"
            ),
        ),
        migrations.AlterField(
            model_name="entryaccountinginformation",
            name="entry",
            field=models.OneToOneField(
                on_delete=django.db.models.deletion.CASCADE,
                related_name="entry_accounting_information",
                to="directory.entry",
                verbose_name="Counterparty",
            ),
        ),
        migrations.AlterField(
            model_name="invoice",
            name="status",
            field=django_fsm.FSMField(
                choices=[
                    ("DRAFT", "Draft"),
                    ("SUBMITTED", "Submitted"),
                    ("APPROVED", "Approved"),
                    ("CANCELLED", "Cancelled"),
                    ("SENT", "Sent"),
                    ("PAID", "Paid"),
                ],
                default="DRAFT",
                max_length=50,
                verbose_name="Status",
            ),
        ),
        migrations.AddField(
            model_name="entryaccountinginformation",
            name="default_invoice_type",
            field=models.ForeignKey(
                blank=True,
                help_text="When invoicinging outstanding booking entries, this invoice type will be assigned to the corresponding invoice",
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                related_name="booking_entries",
                to="wbaccounting.invoicetype",
                verbose_name="Default Invoice Type",
            ),
        ),
        migrations.AddField(
            model_name="invoice",
            name="invoice_type",
            field=models.ForeignKey(
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="invoices",
                to="wbaccounting.invoicetype",
                verbose_name="Type",
            ),
        ),
        migrations.RenameField(
            model_name="bookingentry",
            old_name="resolved_date",
            new_name="payment_date",
        ),
        migrations.AlterField(
            model_name="bookingentry",
            name="payment_date",
            field=models.DateField(blank=True, null=True, verbose_name="Payment Date"),
        ),
        migrations.RemoveField(
            model_name="invoice",
            name="is_counterparty_invoice",
        ),
        migrations.AddField(
            model_name="invoice",
            name="payment_date",
            field=models.DateField(blank=True, null=True, verbose_name="Payment Date"),
        ),
        migrations.AlterField(
            model_name="invoice",
            name="invoice_date",
            field=models.DateField(verbose_name="Invoice Date"),
        ),
        migrations.AlterModelOptions(
            name="entryaccountinginformation",
            options={"verbose_name": "Counterparty", "verbose_name_plural": "Counterparties"},
        ),
        migrations.AlterField(
            model_name="entryaccountinginformation",
            name="email_subject",
            field=models.CharField(default="{{invoice.title}}", max_length=1024, verbose_name="Subject"),
        ),
        migrations.AlterField(
            model_name="entryaccountinginformation",
            name="entry",
            field=models.OneToOneField(
                on_delete=django.db.models.deletion.CASCADE,
                related_name="entry_accounting_information",
                to="directory.entry",
                verbose_name="Linked Counterparty",
            ),
        ),
        migrations.RunSQL(sql="SET CONSTRAINTS ALL IMMEDIATE;"),
        migrations.RunPython(
            strip_html_from_subject,
            reverse_code=migrations.RunPython.noop,
        ),
        migrations.RunSQL(sql="SET CONSTRAINTS ALL DEFERRED;"),
        migrations.RunSQL(sql="SET CONSTRAINTS ALL IMMEDIATE;"),
        migrations.RunPython(
            save_models,
            reverse_code=migrations.RunPython.noop,
        ),
        migrations.RunSQL(sql="SET CONSTRAINTS ALL DEFERRED;"),
    ]
