From 0c756e6ff7f4e31d6694f574a65ef8e1c2e051dd Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Thu, 6 Jun 2024 11:30:31 +0200
Subject: [PATCH] Make creation of participation statuses more efficient

---
 aleksis/apps/alsijil/models.py | 37 ++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index feaba143c..774c1be3e 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -695,30 +695,41 @@ class Documentation(CalendarEvent):
         )
 
     def touch(self):
+        """Ensure that participation statuses are created for this documentation."""
         # TODO: Check for preexisting absences in kolego
-        # TODO: maybe only create if the lesson start is in the past
 
-        if not self.amends:
-            # There is no source to update from
+        if not self.amends or self.datetime_start <= localtime():
+            # There is no source to update from or it's to early
             return
 
         lesson_event: LessonEvent = self.amends
         all_members = lesson_event.all_members
 
-        existing_participations = ParticipationStatus.objects.filter(
-            person__in=all_members, related_documentation=self
+        existing_participations = ParticipationStatus.objects.filter(related_documentation=self)
+        if existing_participations.exists():
+            return
+
+        new_persons = Person.objects.filter(Q(pk__in=[p.pk for p in all_members])).prefetch_related(
+            "member_of"
         )
-        new_persons = Person.objects.filter(
-            Q(pk__in=[p.pk for p in all_members])
-            & ~Q(pk__in=existing_participations.values_list("person", flat=True))
-        ).prefetch_related("member_of")
         new_participations = []
+        new_groups_of_person = []
         for person in new_persons:
-            participation_status = self.build_participation_status(person)
-            participation_status.save()
-            participation_status.groups_of_person.set(person.member_of.all())
+            participation_status = ParticipationStatus.objects.create(
+                person=person,
+                related_documentation=self,
+                datetime_start=self.datetime_start,
+                datetime_end=self.datetime_end,
+                timezone=self.timezone,
+            )
+            new_groups_of_person += [
+                ParticipationStatus.groups_of_person.through(
+                    group=group, participationstatus=participation_status
+                )
+                for group in person.member_of.all()
+            ]
             new_participations.append(participation_status)
-
+        ParticipationStatus.groups_of_person.through.objects.bulk_create(new_groups_of_person)
         return new_participations
 
 
-- 
GitLab