فهرست منبع

Tickets API v1.1

- Added ticket_list/my view allowing you to see your tickets
- Added ability to change your tickets statuses
TonyKurts 1 سال پیش
والد
کامیت
c0b24002c5
8فایلهای تغییر یافته به همراه51 افزوده شده و 21 حذف شده
  1. 0 4
      README.md
  2. 5 1
      api/permissions.py
  3. 1 1
      api/serializers/__init__.py
  4. 19 4
      api/serializers/ticket.py
  5. 1 1
      api/views/__init__.py
  6. 9 3
      api/views/ticket.py
  7. 9 2
      api/views/ticket_list.py
  8. 7 5
      urls.py

+ 0 - 4
README.md

@@ -1,6 +1,3 @@
-<<<<<<< HEAD
-# ShariX Open Tickets
-=======
 # ShariX Open Tickets
 
 Ticketing system implemented as a Django application.
@@ -43,4 +40,3 @@ urlpatterns = [
     # ...
 ] 
 ```
->>>>>>> bf39928 (ShariX Open Tickets v1.0)

+ 5 - 1
api/permissions.py

@@ -16,4 +16,8 @@ class UserTicketAccessPermission(permissions.BasePermission):
             return request.user.is_superuser or obj.ticket_list.group in request.user.groups.all() or obj.assigned_to == request.user
 
         return request.user.is_superuser or request.user.is_staff or obj.created_by == request.user
-    
+
+
+class UserTicketStatusAccessPermission(permissions.BasePermission):
+    def has_object_permission(self, request, view, obj):
+        return request.user.is_superuser or obj.ticket_list.group in request.user.groups.all() or obj.assigned_to == request.user or obj.created_by == request.user

+ 1 - 1
api/serializers/__init__.py

@@ -1,2 +1,2 @@
-from tickets.api.serializers.ticket import TicketSerializer, TicketDetailSerializer
+from tickets.api.serializers.ticket import TicketSerializer, TicketDetailSerializer, TicketStatusSerializer
 from tickets.api.serializers.ticket_list import TicketListSerializer

+ 19 - 4
api/serializers/ticket.py

@@ -6,17 +6,20 @@ from tickets.models import Ticket
 
 
 class BaseTicketSerializer(serializers.ModelSerializer):
+    status = serializers.IntegerField(read_only=True)
+
     def validate(self, data):
         user = self.context['request'].user
+        ticket_list = data.get("ticket_list")
 
-        if not (user.is_superuser or data["ticket_list"].group in user.groups.all()):
-            raise serializers.ValidationError("You don't have access to this list.")
+        if ticket_list:
+            if not (user.is_superuser or ticket_list.group in user.groups.all()):
+                raise serializers.ValidationError("You don't have access to this list.")
         
         return data
 
 
 class TicketSerializer(BaseTicketSerializer):
-    status = serializers.IntegerField(read_only=True)
     note = serializers.CharField(write_only=True, required=False)    
 
     class Meta():
@@ -32,4 +35,16 @@ class TicketDetailSerializer(BaseTicketSerializer):
 
     class Meta():
         model = Ticket
-        fields = "__all__"
+        fields = "__all__"
+
+
+class TicketStatusSerializer(BaseTicketSerializer):
+    status = serializers.IntegerField(read_only=False, required=True)
+    available_statuses = serializers.SerializerMethodField()
+
+    def get_available_statuses(self, obj):
+        return obj.get_available_statuses()
+
+    class Meta():
+        model = Ticket
+        fields = ["id", "available_statuses", "status"]

+ 1 - 1
api/views/__init__.py

@@ -1,2 +1,2 @@
 from tickets.api.views.ticket_list import TicketListDetailAPIView, TicketListListAPIView
-from tickets.api.views.ticket import TicketDetailAPIView, TicketCreateAPIView
+from tickets.api.views.ticket import TicketDetailAPIView, TicketCreateAPIView, TicketStatusAPIView

+ 9 - 3
api/views/ticket.py

@@ -2,8 +2,8 @@ from rest_framework import generics, permissions
 from rest_framework.exceptions import NotFound
 
 from tickets.models import Ticket
-from tickets.api.serializers import TicketDetailSerializer, TicketSerializer
-from tickets.api.permissions import UserTicketAccessPermission
+from tickets.api.serializers import TicketDetailSerializer, TicketSerializer, TicketStatusSerializer
+from tickets.api.permissions import UserTicketAccessPermission, UserTicketStatusAccessPermission
 
 
 class TicketDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
@@ -19,4 +19,10 @@ class TicketCreateAPIView(generics.CreateAPIView):
 
     def perform_create(self, serializer):
         if serializer.is_valid():
-            serializer.save(created_by=self.request.user) 
+            serializer.save(created_by=self.request.user) 
+
+
+class TicketStatusAPIView(generics.RetrieveUpdateAPIView):
+    queryset = Ticket.objects.all()
+    serializer_class = TicketStatusSerializer
+    permission_classes = [permissions.IsAuthenticated & UserTicketStatusAccessPermission]

+ 9 - 2
api/views/ticket_list.py

@@ -15,7 +15,7 @@ class TicketListListAPIView(generics.ListAPIView):
         user = self.request.user
         user_groups_ids = user.groups.all().values_list("pk", flat=True)
         ticket_lists  = TicketList.objects.select_related("group").order_by("group__name", "name")
-        
+
         if not user.is_superuser:
             if user_groups_ids:
                 ticket_lists = ticket_lists.filter(group__id__in=user_groups_ids)
@@ -30,7 +30,14 @@ class TicketListDetailAPIView(generics.ListAPIView):
     serializer_class = TicketSerializer
 
     def get_queryset(self):
-        return Ticket.objects.filter(ticket_list=self.get_object())   
+        tickets = Ticket.objects.all()
+
+        if self.kwargs.get("my"):
+            tickets = tickets.filter(assigned_to=self.request.user)     
+        else:
+            tickets = tickets.filter(ticket_list=self.get_object())
+
+        return tickets
 
     def get_object(self):
         obj = get_object_or_404(TicketList.objects.filter(pk=self.kwargs['pk']))

+ 7 - 5
urls.py

@@ -1,7 +1,7 @@
 from django.urls import path, include
 
 from tickets.views import *
-from tickets.api.views import TicketListDetailAPIView, TicketListListAPIView, TicketDetailAPIView, TicketCreateAPIView
+from tickets.api import views as apiviews
 
 
 app_name = "tickets"
@@ -23,8 +23,10 @@ urlpatterns = [
     path("attachment/remove/<int:attachment_id>/", remove_attachment, name="remove_attachment"),
 
     # API
-    path("api/v1/ticket_list/", TicketListListAPIView.as_view()),
-    path("api/v1/ticket_list/<int:pk>", TicketListDetailAPIView.as_view()),
-    path("api/v1/ticket/", TicketCreateAPIView.as_view()),
-    path("api/v1/ticket/<int:pk>", TicketDetailAPIView.as_view()),
+    path("api/v1/ticket_list/", apiviews.TicketListListAPIView.as_view()),
+    path("api/v1/ticket_list/my/", apiviews.TicketListDetailAPIView.as_view(), {"my": True}),
+    path("api/v1/ticket_list/<int:pk>", apiviews.TicketListDetailAPIView.as_view()),
+    path("api/v1/ticket/", apiviews.TicketCreateAPIView.as_view()),
+    path("api/v1/ticket/<int:pk>", apiviews.TicketDetailAPIView.as_view()),
+    path("api/v1/ticket/<int:pk>/status", apiviews.TicketStatusAPIView.as_view()),
 ]