diff --git a/openslides/agenda/models.py b/openslides/agenda/models.py index 48e26a021..9bcc5d795 100644 --- a/openslides/agenda/models.py +++ b/openslides/agenda/models.py @@ -267,7 +267,7 @@ class Item(RESTModelMixin, models.Model): """ Returns the number of this agenda item. """ - if self.type == self.AGENDA_ITEM: + if not self.is_hidden(): if self.parent is None: sibling_no = self.sibling_no() if config['agenda_numeral_system'] == 'arabic': @@ -281,15 +281,16 @@ class Item(RESTModelMixin, models.Model): def sibling_no(self): """ - Counts how many AGENDA_ITEMS with the same parent (siblings) have a + Counts how many agenda items with the same parent (siblings) have a smaller weight then this item. - Returns this number + 1 or 0 when self is not an AGENDA_ITEM. + Returns this number + 1. """ - return Item.objects.filter( - parent=self.parent, - type=self.AGENDA_ITEM, - weight__lte=self.weight).count() + result = 0 + for item in Item.objects.filter(parent=self.parent, weight__lte=self.weight): + if not item.is_hidden(): + result += 1 + return result class SpeakerManager(models.Manager): diff --git a/openslides/agenda/views.py b/openslides/agenda/views.py index 7b3b7c000..0d7555bf5 100644 --- a/openslides/agenda/views.py +++ b/openslides/agenda/views.py @@ -47,7 +47,7 @@ class ItemViewSet(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericV result = (self.request.user.has_perm('agenda.can_see') and self.request.user.has_perm('agenda.can_see_hidden_items') and self.request.user.has_perm('agenda.can_manage')) - elif self.action == 'speak': + elif self.action in ('speak', 'numbering'): result = (self.request.user.has_perm('agenda.can_see') and self.request.user.has_perm('agenda.can_manage')) else: @@ -219,6 +219,17 @@ class ItemViewSet(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericV response = Response(Item.objects.get_tree()) return response + @list_route(methods=['post']) + def numbering(self, request): + """ + Auto numbering of the agenda according to the config. Manually added + item numbers will be overwritten. + """ + for item in Item.objects.all(): + item.item_number = item.calc_item_no() + item.save() + return Response({'detail': _('The agenda has been numbered.')}) + # Views to generate PDFs diff --git a/tests/integration/agenda/test_viewsets.py b/tests/integration/agenda/test_viewsets.py index 9cfda9c83..c82bec1b1 100644 --- a/tests/integration/agenda/test_viewsets.py +++ b/tests/integration/agenda/test_viewsets.py @@ -2,7 +2,7 @@ from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse from rest_framework.test import APIClient -from openslides.agenda.models import Speaker +from openslides.agenda.models import Item, Speaker from openslides.core.config import config from openslides.core.models import CustomSlide, Projector from openslides.utils.test import TestCase @@ -233,3 +233,53 @@ class Speak(TestCase): else: success = False self.assertTrue(success) + + +class Numbering(TestCase): + """ + Tests view to number the agenda + """ + def setUp(self): + self.client = APIClient() + self.client.login(username='admin', password='admin') + self.item_1 = CustomSlide.objects.create(title='test_title_thuha8eef7ohXar3eech').agenda_item + self.item_2 = CustomSlide.objects.create(title='test_title_eisah7thuxa1eingaeLo').agenda_item + self.item_2.weight = 2 + self.item_2.save() + self.item_2_1 = CustomSlide.objects.create(title='test_title_Qui0audoaz5gie1phish').agenda_item + self.item_2_1.parent = self.item_2 + self.item_2_1.save() + self.item_3 = CustomSlide.objects.create(title='test_title_ah7tphisheineisgaeLo').agenda_item + self.item_3.weight = 3 + self.item_3.save() + + def test_numbering(self): + response = self.client.post(reverse('item-numbering')) + self.assertEqual(response.status_code, 200) + self.assertEqual(Item.objects.get(pk=self.item_1.pk).item_number, '1') + self.assertEqual(Item.objects.get(pk=self.item_2.pk).item_number, '2') + self.assertEqual(Item.objects.get(pk=self.item_2_1.pk).item_number, '2.1') + self.assertEqual(Item.objects.get(pk=self.item_3.pk).item_number, '3') + + def test_roman_numbering(self): + config['agenda_numeral_system'] = 'roman' + + response = self.client.post(reverse('item-numbering')) + + self.assertEqual(response.status_code, 200) + self.assertEqual(Item.objects.get(pk=self.item_1.pk).item_number, 'I') + self.assertEqual(Item.objects.get(pk=self.item_2.pk).item_number, 'II') + self.assertEqual(Item.objects.get(pk=self.item_2_1.pk).item_number, 'II.1') + self.assertEqual(Item.objects.get(pk=self.item_3.pk).item_number, 'III') + + def test_with_hidden_item(self): + self.item_2.type = Item.HIDDEN_ITEM + self.item_2.save() + + response = self.client.post(reverse('item-numbering')) + + self.assertEqual(response.status_code, 200) + self.assertEqual(Item.objects.get(pk=self.item_1.pk).item_number, '1') + self.assertEqual(Item.objects.get(pk=self.item_2.pk).item_number, '') + self.assertEqual(Item.objects.get(pk=self.item_2_1.pk).item_number, '') + self.assertEqual(Item.objects.get(pk=self.item_3.pk).item_number, '2')