From 94c943cdb5761df981093549f98254268095451e Mon Sep 17 00:00:00 2001 From: Finn Stutzenstein Date: Wed, 3 Feb 2021 09:15:13 +0100 Subject: [PATCH] Order point of order speakers in the request order (closes #5816) --- server/openslides/agenda/models.py | 27 +++++++++++++---- .../tests/integration/agenda/test_viewset.py | 30 ++++++++++++++++--- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/server/openslides/agenda/models.py b/server/openslides/agenda/models.py index 385f0316a..b8c8b78ed 100644 --- a/server/openslides/agenda/models.py +++ b/server/openslides/agenda/models.py @@ -6,6 +6,7 @@ from django.contrib.auth.models import AnonymousUser from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models, transaction +from django.db.models import F from django.utils import timezone from openslides.core.config import config @@ -447,12 +448,26 @@ class SpeakerManager(models.Manager): raise OpenSlidesError("Only present users can be on the lists of speakers.") if point_of_order: - weight = ( - self.filter(list_of_speakers=list_of_speakers).aggregate( - models.Min("weight") - )["weight__min"] - or 0 - ) - 1 + # the new point of order speaker (poos) must be inserted between + # the last poos and the first regular waiting speaker + weight = self.filter( + list_of_speakers=list_of_speakers, point_of_order=True + ).aggregate(models.Max("weight"))["weight__max"] + if weight is None: + # noo poos, take the min - 1 + weight = ( + self.filter( + list_of_speakers=list_of_speakers, point_of_order=True + ).aggregate(models.Min("weight"))["weight__min"] + or 1 + ) - 1 + else: + weight += 1 + # we have to add +1 to every weight of non-poo speakers. + self.filter( + list_of_speakers=list_of_speakers, point_of_order=False + ).update(weight=F("weight") + 1) + else: weight = ( self.filter(list_of_speakers=list_of_speakers).aggregate( diff --git a/server/tests/integration/agenda/test_viewset.py b/server/tests/integration/agenda/test_viewset.py index ab30b4cdd..8e30f3cc2 100644 --- a/server/tests/integration/agenda/test_viewset.py +++ b/server/tests/integration/agenda/test_viewset.py @@ -373,7 +373,7 @@ class ManageSpeaker(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(Speaker.objects.all().count(), 1) self.assertTrue(Speaker.objects.get().point_of_order) - self.assertEqual(Speaker.objects.get().weight, -1) + self.assertEqual(Speaker.objects.get().weight, 0) def test_point_of_order_not_enabled(self): self.assertEqual(Speaker.objects.all().count(), 0) @@ -384,7 +384,7 @@ class ManageSpeaker(TestCase): self.assertEqual(response.status_code, 400) self.assertEqual(Speaker.objects.all().count(), 0) - def test_point_of_order_before_other(self): + def test_point_of_order_before_normal(self): config["agenda_enable_point_of_order_speakers"] = True normal_speaker = Speaker.objects.add(self.user, self.list_of_speakers) response = self.client.post( @@ -397,7 +397,7 @@ class ManageSpeaker(TestCase): self.assertTrue(poo_speaker.point_of_order) self.assertEqual(poo_speaker.weight, normal_speaker.weight - 1) - def test_point_of_order_with_normal_speaker(self): + def test_point_of_order_with_same_normal_speaker(self): config["agenda_enable_point_of_order_speakers"] = True Speaker.objects.add(self.admin, self.list_of_speakers) response = self.client.post( @@ -406,7 +406,29 @@ class ManageSpeaker(TestCase): ) self.assertEqual(response.status_code, 200) self.assertEqual(Speaker.objects.all().count(), 2) - self.assertTrue(Speaker.objects.filter(user=self.admin).count(), 2) + self.assertEqual(Speaker.objects.filter(user=self.admin).count(), 2) + + def test_point_of_order_two_poo_speakers(self): + config["agenda_enable_point_of_order_speakers"] = True + # user 2 and user3 are non-poo speakers + self.user2, _ = self.create_user() + self.user3, _ = self.create_user() + Speaker.objects.add(self.user2, self.list_of_speakers) + Speaker.objects.add(self.user3, self.list_of_speakers) + Speaker.objects.add(self.user, self.list_of_speakers, point_of_order=True) + self.assertEqual(Speaker.objects.get(user=self.user).weight, 0) + self.assertEqual(Speaker.objects.get(user=self.user2).weight, 1) + self.assertEqual(Speaker.objects.get(user=self.user3).weight, 2) + response = self.client.post( + reverse("listofspeakers-manage-speaker", args=[self.list_of_speakers.pk]), + {"point_of_order": True}, + ) + self.assertEqual(response.status_code, 200) + self.assertEqual(Speaker.objects.all().count(), 4) + self.assertEqual(Speaker.objects.get(user=self.user).weight, 0) + self.assertEqual(Speaker.objects.get(user=self.admin).weight, 1) + self.assertEqual(Speaker.objects.get(user=self.user2).weight, 2) + self.assertEqual(Speaker.objects.get(user=self.user3).weight, 3) def test_point_of_order_twice(self): config["agenda_enable_point_of_order_speakers"] = True