diff --git a/core/inventory/api_v2.py b/core/inventory/api_v2.py index 60f0292..39052f8 100644 --- a/core/inventory/api_v2.py +++ b/core/inventory/api_v2.py @@ -1,15 +1,20 @@ from django.urls import re_path from django.contrib.auth.decorators import permission_required -from rest_framework import routers, viewsets +from rest_framework import routers, viewsets, status from rest_framework.decorators import api_view, permission_classes from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated +from asgiref.sync import async_to_sync +from channels.layers import get_channel_layer -from inventory.models import Event, Container, Item -from inventory.serializers import EventSerializer, ContainerSerializer, ItemSerializer, SearchResultSerializer +from inventory.models import Event, Container, Item, Comment +from inventory.serializers import EventSerializer, ContainerSerializer, ItemSerializer, SearchResultSerializer, \ + CommentSerializer from base64 import b64decode +from notify_sessions.models import SystemEvent + class EventViewSet(viewsets.ModelViewSet): serializer_class = EventSerializer @@ -71,6 +76,31 @@ def item(request, event_slug): return Response(status=400) +@api_view(['POST']) +@permission_classes([IsAuthenticated]) +@permission_required('tickets.add_comment', raise_exception=True) +def add_comment(request, event_slug, id): + event = None + if event_slug != 'none': + event = Event.objects.get(slug=event_slug) + item = Item.objects.get(event=event, id=id) + if not request.user.has_event_perm(event, 'view_item'): + return Response(status=403) + if 'comment' not in request.data or request.data['comment'] == '': + return Response({'status': 'error', 'message': 'missing comment'}, status=status.HTTP_400_BAD_REQUEST) + comment = Comment.objects.create( + item=item, + comment=request.data['comment'], + ) + systemevent = SystemEvent.objects.create(type='comment added', reference=comment.id) + channel_layer = get_channel_layer() + async_to_sync(channel_layer.group_send)( + 'general', {"type": "generic.event", "name": "send_message_to_frontend", "event_id": systemevent.id, + "message": "comment added"} + ) + return Response(CommentSerializer(comment).data, status=status.HTTP_201_CREATED) + + @api_view(['GET', 'PUT', 'DELETE', 'PATCH']) @permission_classes([IsAuthenticated]) def item_by_id(request, event_slug, id): @@ -117,5 +147,6 @@ urlpatterns = router.urls + [ re_path(r'^(?P[\w-]+)/items/$', item, name='item'), re_path(r'^(?P[\w-]+)/items/(?P[-A-Za-z0-9+/]*={0,3})/$', search_items, name='search_items'), re_path(r'^(?P[\w-]+)/item/$', item, name='item'), + re_path(r'^(?P[\w-]+)/item/(?P\d+)/comment/$', add_comment, name='add_comment'), re_path(r'^(?P[\w-]+)/item/(?P\d+)/$', item_by_id, name='item_by_id'), ] diff --git a/core/inventory/serializers.py b/core/inventory/serializers.py index f13235c..c349e19 100644 --- a/core/inventory/serializers.py +++ b/core/inventory/serializers.py @@ -3,7 +3,7 @@ from rest_framework import serializers from rest_framework.relations import SlugRelatedField from files.models import File -from inventory.models import Event, Container, Item +from inventory.models import Event, Container, Item, Comment from inventory.shared_serializers import BasicItemSerializer from mail.models import EventAddress from tickets.shared_serializers import BasicIssueSerializer @@ -25,6 +25,7 @@ class EventSerializer(serializers.ModelSerializer): dict['addresses'] = [EventAddress.objects.get_or_create(address=x)[0] for x in addresses] return dict + class ContainerSerializer(serializers.ModelSerializer): itemCount = serializers.SerializerMethodField() @@ -37,6 +38,18 @@ class ContainerSerializer(serializers.ModelSerializer): return len(instance.items) +class CommentSerializer(serializers.ModelSerializer): + + def validate(self, attrs): + if 'comment' not in attrs or attrs['comment'] == '': + raise serializers.ValidationError('comment cannot be empty') + return attrs + + class Meta: + model = Comment + fields = ('id', 'comment', 'timestamp', 'item') + + class ItemSerializer(BasicItemSerializer): timeline = serializers.SerializerMethodField() dataImage = serializers.CharField(write_only=True, required=False) diff --git a/core/testdata.py b/core/testdata.py new file mode 100644 index 0000000..e69de29 diff --git a/web/src/components/TimelineMail.vue b/web/src/components/TimelineMail.vue index 065d56a..6c43267 100644 --- a/web/src/components/TimelineMail.vue +++ b/web/src/components/TimelineMail.vue @@ -1,6 +1,5 @@