From 5d738d2fad47efa9d0a20ae2d3aa23aa7290a317 Mon Sep 17 00:00:00 2001
From: Tom Teichler <tom.teichler@teckids.org>
Date: Fri, 18 Feb 2022 22:08:13 +0100
Subject: [PATCH] Rewrite models and generate migrations

---
 .../apps/paweljong/migrations/0001_initial.py |  2 +-
 .../0003_alter_event_feedback_aspects.py      | 18 ++++++
 .../0004_richtext_field_information.py        | 30 +++++++++
 ...5_eventregistration_medical_information.py | 18 ++++++
 .../migrations/0006_unique_constraints.py     | 25 ++++++++
 aleksis/apps/paweljong/models.py              | 64 ++++++++++++++-----
 6 files changed, 140 insertions(+), 17 deletions(-)
 create mode 100644 aleksis/apps/paweljong/migrations/0003_alter_event_feedback_aspects.py
 create mode 100644 aleksis/apps/paweljong/migrations/0004_richtext_field_information.py
 create mode 100644 aleksis/apps/paweljong/migrations/0005_eventregistration_medical_information.py
 create mode 100644 aleksis/apps/paweljong/migrations/0006_unique_constraints.py

diff --git a/aleksis/apps/paweljong/migrations/0001_initial.py b/aleksis/apps/paweljong/migrations/0001_initial.py
index 2ca1cd2..3921c4c 100644
--- a/aleksis/apps/paweljong/migrations/0001_initial.py
+++ b/aleksis/apps/paweljong/migrations/0001_initial.py
@@ -11,7 +11,7 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
-        ('core', '0028_alter_globalpermissions_options'),
+        ('core', '0035_preference_model_unique'),
         ('sites', '0002_alter_domain_unique'),
     ]
 
diff --git a/aleksis/apps/paweljong/migrations/0003_alter_event_feedback_aspects.py b/aleksis/apps/paweljong/migrations/0003_alter_event_feedback_aspects.py
new file mode 100644
index 0000000..6d1d673
--- /dev/null
+++ b/aleksis/apps/paweljong/migrations/0003_alter_event_feedback_aspects.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.12 on 2022-02-13 14:44
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('paweljong', '0002_event_website'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='event',
+            name='feedback_aspects',
+            field=models.ManyToManyField(blank=True, null=True, related_name='event', to='paweljong.FeedbackAspect', verbose_name='Feedback aspects'),
+        ),
+    ]
diff --git a/aleksis/apps/paweljong/migrations/0004_richtext_field_information.py b/aleksis/apps/paweljong/migrations/0004_richtext_field_information.py
new file mode 100644
index 0000000..428b547
--- /dev/null
+++ b/aleksis/apps/paweljong/migrations/0004_richtext_field_information.py
@@ -0,0 +1,30 @@
+# Generated by Django 3.2.12 on 2022-02-16 18:52
+
+import ckeditor.fields
+from django.db import migrations
+import django_iban.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('paweljong', '0003_alter_event_feedback_aspects'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='event',
+            name='website',
+        ),
+        migrations.AddField(
+            model_name='event',
+            name='information',
+            field=ckeditor.fields.RichTextField(default='', verbose_name='Information about the event'),
+            preserve_default=False,
+        ),
+        migrations.AlterField(
+            model_name='eventregistration',
+            name='iban',
+            field=django_iban.fields.IBANField(blank=True, enforce_database_constraint=True, max_length=34, null=True, verbose_name='IBAN (for SEPA direct debit)'),
+        ),
+    ]
diff --git a/aleksis/apps/paweljong/migrations/0005_eventregistration_medical_information.py b/aleksis/apps/paweljong/migrations/0005_eventregistration_medical_information.py
new file mode 100644
index 0000000..23bd625
--- /dev/null
+++ b/aleksis/apps/paweljong/migrations/0005_eventregistration_medical_information.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.12 on 2022-02-16 21:05
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('paweljong', '0004_richtext_field_information'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='eventregistration',
+            name='medical_information',
+            field=models.TextField(blank=True, default='', verbose_name='Medical information / intolerances'),
+        ),
+    ]
diff --git a/aleksis/apps/paweljong/migrations/0006_unique_constraints.py b/aleksis/apps/paweljong/migrations/0006_unique_constraints.py
new file mode 100644
index 0000000..945d2e5
--- /dev/null
+++ b/aleksis/apps/paweljong/migrations/0006_unique_constraints.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.2.12 on 2022-02-18 14:08
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('paweljong', '0005_eventregistration_medical_information'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='eventregistration',
+            options={'verbose_name': 'Event registration', 'verbose_name_plural': 'Event registrations'},
+        ),
+        migrations.AddConstraint(
+            model_name='eventfeedback',
+            constraint=models.UniqueConstraint(fields=('person', 'event'), name='unique_person_feedback_per_event'),
+        ),
+        migrations.AddConstraint(
+            model_name='eventregistration',
+            constraint=models.UniqueConstraint(fields=('person', 'event'), name='unique_person_registration_per_event'),
+        ),
+    ]
diff --git a/aleksis/apps/paweljong/models.py b/aleksis/apps/paweljong/models.py
index c8e21ca..2b325aa 100644
--- a/aleksis/apps/paweljong/models.py
+++ b/aleksis/apps/paweljong/models.py
@@ -1,12 +1,16 @@
+from datetime import datetime
+
 from django.db import models
-from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 
+from ckeditor.fields import RichTextField
 from django_iban.fields import IBANField
 
 from aleksis.core.mixins import ExtensibleModel
 from aleksis.core.models import Group, Person
 
+from .util import generate_code
+
 
 class FeedbackAspect(ExtensibleModel):
     aspect = models.CharField(max_length=100)
@@ -33,50 +37,54 @@ class Event(ExtensibleModel):
     # Other details
     cost = models.IntegerField(verbose_name=_("Cost in €"))
     max_participants = models.PositiveSmallIntegerField(verbose_name=_("Maximum participants"))
-    website = models.CharField(verbose_name=_("Website of event"), max_length=255)
+    information = RichTextField(verbose_name=_("Information about the event"))
 
     # Feedback
     feedback_aspects = models.ManyToManyField(
-        FeedbackAspect, verbose_name=_("Feedback aspects"), related_name="event"
+        FeedbackAspect,
+        verbose_name=_("Feedback aspects"),
+        related_name="event",
+        null=True,
+        blank=True,
     )
 
     def __str__(self) -> str:
         return self.display_name
 
     def can_register(self, request=None):
-        now = timezone.now()
+        now = datetime.today().date()
 
         if request and request.user.is_authenticated:
+            if request.user.person in self.linked_group.members.all():
+                return False
+
             if (
                 Voucher.objects.filter(event=self, person=request.user.person, used=False).count()
                 > 0
             ):
                 return True
 
-        if self.group.members.count() >= self.max_participants:
+        if self.linked_group.members.count() >= self.max_participants:
             return False
 
         if self.date_registration:
-            return self.date_registration >= timezone.now()
-        return self.date_event > timezone.now()
+            return self.date_registration >= now
+        return self.date_event > now
 
     @property
     def booked_percentage(self):
-        return self.group.members.count() / self.max_participants * 100
+        return self.linked_group.members.count() / self.max_participants * 100
 
     @property
     def members_persons(self):
-        return self.group.members.all()
+        return self.linked_group.members.all()
 
     @property
     def owners_persons(self):
-        return self.group.owners.all()
+        return self.linked_group.owners.all()
 
 
 class EventFeedback(ExtensibleModel):
-    class Meta:
-        verbose_name = _("Event feedback")
-        verbose_name_plural = _("Event feedbacks")
 
     COMMENT_CHOICES = [
         ("first", _("Only first name")),
@@ -113,6 +121,15 @@ class EventFeedback(ExtensibleModel):
         choices=LICENCE_CHOICES, verbose_name=_("Photo licence"), max_length=255
     )
 
+    class Meta:
+        verbose_name = _("Event feedback")
+        verbose_name_plural = _("Event feedbacks")
+        constraints = [
+            models.UniqueConstraint(
+                fields=["person", "event"], name="unique_person_feedback_per_event"
+            )
+        ]
+
 
 class Voucher(ExtensibleModel):
     class Meta:
@@ -148,17 +165,22 @@ class Voucher(ExtensibleModel):
     def __str__(self) -> str:
         return self.code
 
+    def save(self, *args, **kwargs):
+        if not self.code:
+            self.code = generate_code()
+        super().save(*args, **kwargs)
+
 
 class EventRegistration(ExtensibleModel):
-    class Meta:
-        verbose_name = _("Registration")
-        verbose_name_plural = _("Registrations")
 
     event = models.ForeignKey(Event, on_delete=models.CASCADE, verbose_name=_("Event"))
     person = models.ForeignKey(Person, on_delete=models.CASCADE, verbose_name=_("Person"))
     date_registred = models.DateTimeField(auto_now_add=True, verbose_name=_("Registration date"))
 
     comment = models.TextField(verbose_name=_("Comment / remarks"), blank=True, default="")
+    medical_information = models.TextField(
+        verbose_name=_("Medical information / intolerances"), blank=True, default=""
+    )
     channel = models.CharField(verbose_name=_("Channel"), max_length=255, blank=True, default="")
     voucher = models.ForeignKey(
         Voucher,
@@ -174,6 +196,7 @@ class EventRegistration(ExtensibleModel):
         verbose_name=_("IBAN (for SEPA direct debit)"),
         enforce_database_constraint=True,
         null=True,
+        blank=True,
     )
 
     accept_terms = models.BooleanField(verbose_name=_("Delcaration of consent by parents"))
@@ -184,3 +207,12 @@ class EventRegistration(ExtensibleModel):
 
     def __str__(self) -> str:
         return f"{self.event}, {self.person.first_name} {self.person.last_name}"
+
+    class Meta:
+        verbose_name = _("Event registration")
+        verbose_name_plural = _("Event registrations")
+        constraints = [
+            models.UniqueConstraint(
+                fields=["person", "event"], name="unique_person_registration_per_event"
+            )
+        ]
-- 
GitLab