diff --git a/openslides/assignments/serializers.py b/openslides/assignments/serializers.py index 3effc730b..72a776852 100644 --- a/openslides/assignments/serializers.py +++ b/openslides/assignments/serializers.py @@ -1,12 +1,15 @@ +from django.contrib.contenttypes.models import ContentType from django.db import transaction from django.utils.translation import ugettext as _ +from openslides.agenda.models import Item from openslides.utils.rest_api import ( DictField, IntegerField, ListField, ListSerializer, ModelSerializer, + SerializerMethodField, ValidationError, ) @@ -156,6 +159,7 @@ class AssignmentFullSerializer(ModelSerializer): """ Serializer for assignment.models.Assignment objects. With all polls. """ + agenda_items = SerializerMethodField() assignment_related_users = AssignmentRelatedUserSerializer(many=True, read_only=True) polls = AssignmentAllPollSerializer(many=True, read_only=True) @@ -170,14 +174,22 @@ class AssignmentFullSerializer(ModelSerializer): 'assignment_related_users', 'poll_description_default', 'polls', - 'tags',) + 'tags', + 'agenda_items',) + + def get_agenda_items(self, obj): + """ + Returns a list of ids of all agenda items that are related to this + assignment. + """ + assignment_content_type = ContentType.objects.get_for_model(obj) + return (item.pk for item in Item.objects.filter(content_type=assignment_content_type, object_id=obj.pk)) class AssignmentShortSerializer(AssignmentFullSerializer): """ Serializer for assignment.models.Assignment objects. Without unpublished poll. """ - assignment_related_users = AssignmentRelatedUserSerializer(many=True, read_only=True) polls = AssignmentShortPollSerializer(many=True, read_only=True) class Meta: @@ -191,4 +203,5 @@ class AssignmentShortSerializer(AssignmentFullSerializer): 'assignment_related_users', 'poll_description_default', 'polls', - 'tags',) + 'tags', + 'agenda_items',) diff --git a/openslides/assignments/views.py b/openslides/assignments/views.py index f249df58e..e53d5f6e5 100644 --- a/openslides/assignments/views.py +++ b/openslides/assignments/views.py @@ -15,6 +15,7 @@ from reportlab.platypus import ( TableStyle, ) +from openslides.agenda.models import Item from openslides.config.api import config from openslides.users.models import Group, User # TODO: remove this from openslides.utils.pdf import stylesheet @@ -213,6 +214,25 @@ class AssignmentViewSet(ModelViewSet): assignment.create_poll() return Response({'detail': _(' Poll created successfully.')}) + @detail_route(methods=['post']) + def create_agenda_item(self, request, pk=None): + """ + Speacial view endpoint to create an agenda item that is related to + this assignment. + """ + # Check permission. + if not request.user.has_perm('assignments.can_manage'): + self.permission_denied(request) + + # Retrieve motion. + assignment = self.get_object() + + # Create agenda item. + Item.objects.create(content_object=assignment) + + # Initiate response. + return Response({'detail': _('Agenda item successfully created.')}) + class AssignmentPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet): """ diff --git a/openslides/motions/serializers.py b/openslides/motions/serializers.py index e5ff3ccd5..b78194004 100644 --- a/openslides/motions/serializers.py +++ b/openslides/motions/serializers.py @@ -1,12 +1,15 @@ +from django.contrib.contenttypes.models import ContentType from django.db import transaction from django.utils.translation import ugettext as _ +from openslides.agenda.models import Item from openslides.config.api import config from openslides.utils.rest_api import ( CharField, IntegerField, ModelSerializer, PrimaryKeyRelatedField, + SerializerMethodField, ValidationError, ) @@ -138,6 +141,7 @@ class MotionSerializer(ModelSerializer): Serializer for motion.models.Motion objects. """ active_version = PrimaryKeyRelatedField(read_only=True) + agenda_items = SerializerMethodField() log_messages = MotionLogSerializer(many=True, read_only=True) polls = MotionPollSerializer(many=True, read_only=True) reason = CharField(allow_blank=True, required=False, write_only=True) @@ -165,6 +169,7 @@ class MotionSerializer(ModelSerializer): 'workflow', 'tags', 'attachments', + 'agenda_items', 'polls', 'log_messages',) read_only_fields = ('parent',) # Some other fields are also read_only. See definitions above. @@ -228,3 +233,11 @@ class MotionSerializer(ModelSerializer): attr.add(*validated_data[key]) return motion + + def get_agenda_items(self, obj): + """ + Returns a list of ids of all agenda items that are related to this + motion. + """ + motion_content_type = ContentType.objects.get_for_model(obj) + return (item.pk for item in Item.objects.filter(content_type=motion_content_type, object_id=obj.pk)) diff --git a/openslides/motions/views.py b/openslides/motions/views.py index 8c8e06128..22406fdad 100644 --- a/openslides/motions/views.py +++ b/openslides/motions/views.py @@ -6,6 +6,7 @@ from django.utils.translation import ugettext_noop from reportlab.platypus import SimpleDocTemplate from rest_framework import status +from openslides.agenda.models import Item from openslides.config.api import config from openslides.utils.rest_api import ( ModelViewSet, @@ -244,6 +245,28 @@ class MotionViewSet(ModelViewSet): person=request.user) return Response({'detail': message}) + @detail_route(methods=['post']) + def create_agenda_item(self, request, pk=None): + """ + Speacial view endpoint to create an agenda item that is related to + this motion. + """ + # Check permission. + if not request.user.has_perm('motions.can_manage'): + self.permission_denied(request) + + # Retrieve motion. + motion = self.get_object() + + # Create agenda item. + Item.objects.create(content_object=motion) + + # Write the log message and initiate response. + motion.write_log( + message_list=[ugettext_noop('Agenda item created')], + person=request.user) + return Response({'detail': _('Agenda item successfully created.')}) + class PollPDFView(PDFView): """