Fixed sorting of motions in a category. Changed identifiers of amendments during sorting. Fixed #2701.

This commit is contained in:
Norman Jäckel 2016-12-03 21:59:13 +01:00 committed by Norman Jäckel
parent 224ba797a2
commit e180b1df29
3 changed files with 52 additions and 10 deletions

View File

@ -680,6 +680,15 @@ class Motion(RESTModelMixin, models.Model):
""" """
return config['motions_amendments_enabled'] and self.parent is not None return config['motions_amendments_enabled'] and self.parent is not None
def get_amendments_deep(self):
"""
Generator that yields all amendments of this motion including all
amendment decendents.
. """
for amendment in self.amendments.all():
yield amendment
yield from amendment.get_amendments_deep()
def get_search_index_string(self): def get_search_index_string(self):
""" """
Returns a string that can be indexed for the search. Returns a string that can be indexed for the search.

View File

@ -1869,6 +1869,7 @@ angular.module('OpenSlidesApp.motions.site', [
Category.bindOne(category.id, $scope, 'category'); Category.bindOne(category.id, $scope, 'category');
Motion.bindAll({}, $scope, 'motions'); Motion.bindAll({}, $scope, 'motions');
$scope.filter = { category_id: category.id, $scope.filter = { category_id: category.id,
parent_id: null,
orderBy: 'identifier' }; orderBy: 'identifier' };
$scope.$watch( $scope.$watch(

View File

@ -1,4 +1,5 @@
import base64 import base64
import re
from django.contrib.staticfiles import finders from django.contrib.staticfiles import finders
from django.db import IntegrityError, transaction from django.db import IntegrityError, transaction
@ -404,10 +405,16 @@ class CategoryViewSet(ModelViewSet):
Send POST {'motions': [<list of motion ids>]} to sort the given Send POST {'motions': [<list of motion ids>]} to sort the given
motions in a special order. Ids of motions which do not belong to motions in a special order. Ids of motions which do not belong to
the category are just ignored. Send just POST {} to sort all the category are just ignored. Send just POST {} to sort all
motions in the category by id. motions in the category by database id.
Amendments will get a new identifier prefix if the old prefix matches
the old parent motion identifier.
""" """
category = self.get_object() category = self.get_object()
number = 0 number = 0
instances = []
# Prepare ordered list of motions.
if not category.prefix: if not category.prefix:
prefix = '' prefix = ''
else: else:
@ -420,25 +427,50 @@ class CategoryViewSet(ModelViewSet):
motion_dict[motion.pk] = motion motion_dict[motion.pk] = motion
motions = [motion_dict[pk] for pk in motion_list] motions = [motion_dict[pk] for pk in motion_list]
instances = [] # Change identifiers.
try: try:
with transaction.atomic(): with transaction.atomic():
for motion in motions: # Collect old and new identifiers.
motion.identifier = None motions_to_be_sorted = []
motion.skip_autoupdate = True # This line is to skip agenda item autoupdate. See agenda/signals.py.
motion.save(skip_autoupdate=True)
for motion in motions: for motion in motions:
if motion.is_amendment(): if motion.is_amendment():
parent_identifier = motion.parent.identifier or '' parent_identifier = motion.parent.identifier or ''
prefix = '%s %s ' % (parent_identifier, config['motions_amendments_prefix']) prefix = '%s %s ' % (parent_identifier, config['motions_amendments_prefix'])
number += 1 number += 1
identifier = '%s%s' % (prefix, motion.extend_identifier_number(number)) new_identifier = '%s%s' % (prefix, motion.extend_identifier_number(number))
motion.identifier = identifier motions_to_be_sorted.append({
motion.identifier_number = number 'motion': motion,
'old_identifier': motion.identifier,
'new_identifier': new_identifier,
'number': number
})
# Remove old identifiers
for motion in motions:
motion.identifier = None
motion.skip_autoupdate = True # This line is to skip agenda item autoupdate. See agenda/signals.py.
motion.save(skip_autoupdate=True)
# Set new identifers and change identifiers of amendments.
for obj in motions_to_be_sorted:
motion = obj['motion']
motion.identifier = obj['new_identifier']
motion.identifier_number = obj['number']
motion.save(skip_autoupdate=True) motion.save(skip_autoupdate=True)
instances.append(motion) instances.append(motion)
instances.append(motion.agenda_item) instances.append(motion.agenda_item)
# Change identifiers of amendments.
for child in motion.get_amendments_deep():
if child.identifier.startswith(obj['old_identifier']):
child.identifier = re.sub(
obj['old_identifier'],
obj['new_identifier'],
child.identifier,
count=1)
child.skip_autoupdate = True # This line is to skip agenda item autoupdate. See agenda/signals.py.
child.save(skip_autoupdate=True)
instances.append(child)
instances.append(child.agenda_item)
except IntegrityError: except IntegrityError:
message = _('Error: At least one identifier of this category does ' message = _('Error: At least one identifier of this category does '
'already exist in another category.') 'already exist in another category.')