# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2021-06-01 01:27
from __future__ import unicode_literals

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


def update_subject_payments(apps, schema_editor):
    SubjectPayment = apps.get_model("leprikon", "SubjectPayment")

    # delete zero amount payments just to be sure
    SubjectPayment.objects.filter(related_payment__amount=Decimal("0")).update(related_payment=None)
    SubjectPayment.objects.filter(amount=Decimal("0")).delete()

    # fix inconsistent payment types :rolling eyes:
    for wrong, correct in (
        ("RETURN_CASH", "PAYMENT_CASH"),
        ("RETURN_BANK", "PAYMENT_BANK"),
        ("RETURN_TRANSFER", "PAYMENT_TRANSFER"),
    ):
        SubjectPayment.objects.filter(amount__gt=Decimal("0"), payment_type=wrong).update(payment_type=correct)
    for wrong, correct in (
        ("PAYMENT_CASH", "RETURN_CASH"),
        ("PAYMENT_BANK", "RETURN_BANK"),
        ("PAYMENT_ONLINE", "RETURN_BANK"),
        ("PAYMENT_TRANSFER", "RETURN_TRANSFER"),
    ):
        SubjectPayment.objects.filter(amount__lt=Decimal("0"), payment_type=wrong).update(payment_type=correct)

    # set target registration on payments
    SubjectPayment.objects.filter(amount__gt=Decimal("0")).update(
        target_registration=models.F("registration"),
    )

    # set source registration and amount on returned payments
    SubjectPayment.objects.filter(amount__lt=Decimal("0")).update(
        source_registration=models.F("registration"),
        amount=0 - models.F("amount"),
    )

    # set source registration on transfer payments and remove related returned payments
    for payment in SubjectPayment.objects.filter(
        payment_type="PAYMENT_TRANSFER",
        related_payment__payment_type="RETURN_TRANSFER",
        related_payment__amount=models.F("amount"),
    ).select_related("related_payment"):
        payment.source_registration_id = payment.related_payment.registration_id
        payment.note = f"{payment.note}, {payment.related_payment.note}".strip(", ")
        payment.save()
        SubjectPayment.objects.filter(related_payment=payment.related_payment).update(related_payment=None)
        payment.related_payment.delete()
    # also in other direction
    for payment in SubjectPayment.objects.filter(
        payment_type="RETURN_TRANSFER",
        related_payment__payment_type="PAYMENT_TRANSFER",
        related_payment__amount=models.F("amount"),
    ).select_related("related_payment"):
        payment.related_payment.source_registration_id = payment.registration_id
        payment.related_payment.note = f"{payment.related_payment.note}, {payment.note}".strip(", ")
        payment.related_payment.save()
        SubjectPayment.objects.filter(related_payment=payment).update(related_payment=None)
        payment.delete()

    # update obsolete payment types
    SubjectPayment.objects.filter(
        payment_type__in=("PAYMENT_TRANSFER", "RETURN_TRANSFER"),
    ).update(payment_type="TRANSFER")

    # find related payments
    for payment in SubjectPayment.objects.filter(
        payment_type="TRANSFER",
        source_registration=None,
    ).select_related("target_registration"):
        related_payment = SubjectPayment.objects.filter(
            payment_type="TRANSFER",
            target_registration=None,
            amount=payment.amount,
            source_registration__user_id=payment.target_registration.user_id,
            accounted__date=payment.accounted.date(),
        ).first()
        if related_payment:
            payment.source_registration_id = related_payment.source_registration_id
            payment.save()
            related_payment.delete()


class Migration(migrations.Migration):

    dependencies = [
        ("django_pays", "0001_initial"),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ("bankreader", "0003_transaction_account_statement_cleanup"),
        ("leprikon", "0058_agegroup_min_max_age"),
    ]

    operations = [
        migrations.AddField(
            model_name="subjectpayment",
            name="source_registration",
            field=models.ForeignKey(
                blank=True,
                help_text="The payment will be deducted from this registration.",
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="returned_payments",
                to="leprikon.SubjectRegistration",
                verbose_name="source registration",
            ),
        ),
        migrations.AddField(
            model_name="subjectpayment",
            name="target_registration",
            field=models.ForeignKey(
                blank=True,
                help_text="The payment will be added to this registration.",
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="received_payments",
                to="leprikon.SubjectRegistration",
                verbose_name="target registration",
            ),
        ),
        migrations.RunPython(update_subject_payments),
    ]
