# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-10-10 19:41
from __future__ import unicode_literals

from collections import defaultdict
from datetime import date
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


def create_courseregistration_periods(apps, schema_editor):
    CourseDiscount = apps.get_model('leprikon', 'CourseDiscount')
    CourseRegistration = apps.get_model('leprikon', 'CourseRegistration')
    CourseRegistrationPeriod = apps.get_model('leprikon', 'CourseRegistrationPeriod')
    SchoolYearPeriod = apps.get_model('leprikon', 'SchoolYearPeriod')

    today = date.today()
    periods = defaultdict(list)
    for period in SchoolYearPeriod.objects.all():
        period.first = period.school_year_division_id not in periods
        periods[period.school_year_division_id].append(period)

    for registration in CourseRegistration.objects.annotate(
        school_year_division_id=models.F('subject__course__school_year_division_id')
    ).iterator():
        CourseRegistrationPeriod.objects.bulk_create(
            CourseRegistrationPeriod(
                registration=registration,
                period=period,
                payment_requested=(
                    period.due_from < today
                    if registration.payment_requested
                    else False
                ),
            )
            for period in periods[registration.school_year_division_id]
            if period.end >= registration.created.date() and (
                registration.canceled is None or
                period.start <= registration.canceled.date() or
                period.first
            )
        )
    CourseDiscount.objects.update(
        registration_period_id=models.Subquery(
            CourseRegistrationPeriod.objects.filter(
                registration_id=models.OuterRef('registration_id'),
                period_id=models.OuterRef('period_id'),
            ).values('id')[:1]
        ),
    )
    invalid_course_discounts = CourseDiscount.objects.filter(registration_period=None)
    invalid_course_discounts.delete()


class Migration(migrations.Migration):

    dependencies = [
        ('leprikon', '0055_schoolyearblockplugin'),
    ]

    operations = [
        migrations.CreateModel(
            name='CourseRegistrationPeriod',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('payment_requested', models.BooleanField(default=False, verbose_name='payment requested')),
                ('period', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='course_registration_periods', to='leprikon.SchoolYearPeriod', verbose_name='period')),
                ('registration', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_registration_periods', to='leprikon.CourseRegistration', verbose_name='registration')),
            ],
            options={
                'ordering': ('period__start',),
                'verbose_name': 'registered period',
                'verbose_name_plural': 'registered periods',
            },
        ),
        migrations.AddField(
            model_name='course',
            name='allow_period_selection',
            field=models.BooleanField(default=False, help_text='allow user to choose school year periods on registration form', verbose_name='allow period selection'),
        ),
        migrations.AddField(
            model_name='subject',
            name='min_due_date_days',
            field=models.PositiveIntegerField(default=3, verbose_name='minimal number of days to due date'),
        ),
        migrations.AddField(
            model_name='coursediscount',
            name='registration_period',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='discounts', to='leprikon.CourseRegistrationPeriod', verbose_name='period'),
        ),
        migrations.RunPython(create_courseregistration_periods),
    ]
