from rest_framework import generics, permissions from rest_framework.response import Response from rest_framework.views import APIView from .models import Ticket, Message, Attachment from .serializers import TicketListSerializer, MessageSerializer, TicketSerializer, AttachmentSerializer, ContactUsSerializer from utils.pagination import StructurePagination from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes from rest_framework.permissions import IsAuthenticated from rest_framework.parsers import MultiPartParser, FormParser from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiExample, OpenApiTypes, OpenApiResponse from rest_framework import status from django.shortcuts import get_object_or_404 class AttachmentDeleteView(APIView): permission_classes = [IsAuthenticated] serializer_class = [AttachmentSerializer] def delete(self, request, pk): attachment_instance = get_object_or_404(Attachment, pk=pk) if attachment_instance.uploaded_by == request.user: attachment_instance.delete() return Response(status=status.HTTP_204_NO_CONTENT) return Response({'detail': 'این فایل توسط شما اپلود نشده'}) class AttachmentUploadView(APIView): permission_classes = [IsAuthenticated] parser_classes = [MultiPartParser, FormParser] @extend_schema( request=AttachmentSerializer, responses={201: AttachmentSerializer}, description="upload an attachment (file).", ) def post(self, request, *args, **kwargs): serializer = AttachmentSerializer(data=request.data, context={'request': request}) if serializer.is_valid(): serializer.save(uploaded_by=request.user) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # class TicketCreateView(generics.CreateAPIView): # queryset = Ticket.objects.all() # serializer_class = TicketSerializer # permission_classes = [permissions.IsAuthenticated] # def perform_create(self, serializer): # message = serializer.validated_data.get('message') # ticket = serializer.validated_data.get('ticket') # serializer.save(customer=self.request.user) class TicketCreateView(APIView): serializer_class = TicketSerializer permission_classes = [permissions.IsAuthenticated] def post(self, request): new_ticket_ser = self.serializer_class(data=request.data, context={'request': request}) if new_ticket_ser.is_valid(): new_ticket_ser.save(customer=request.user) return Response(new_ticket_ser.data, status=status.HTTP_201_CREATED) else: return Response(new_ticket_ser.errors, status=status.HTTP_400_BAD_REQUEST) class TicketListView(APIView): serializer_class = TicketListSerializer permission_classes = [permissions.IsAuthenticated] pagination_class = StructurePagination @extend_schema( parameters=[ OpenApiParameter( name="limit", description="لیمیتش", required=False, type=OpenApiTypes.INT, ), OpenApiParameter( name="offset", description="افستش", required=False, type=OpenApiTypes.INT, ), OpenApiParameter( name="filter", description=( "filter results by one of the following fields:\n" "`in_progress`, `closed`, `resolved`." ), required=False, type=OpenApiTypes.STR, ), OpenApiParameter( name="sort", description=( "Sort results by one of the following fields:\n" " `created_at`, `-created_at`." "\nPrefix with `-` for descending order." ), required=False, type=OpenApiTypes.STR, ), ], responses={ 200: TicketListSerializer(many=True), 404: OpenApiTypes.OBJECT, }, ) def get(self, request): tickets = Ticket.objects.filter(customer=request.user) filter_by = request.query_params.get('filter', None) sort = request.query_params.get('sort', None) if filter_by: tickets = tickets.filter(status=str(filter_by)) if sort: if sort not in ['created_at', '-created_at']: return Response({'detail': 'wrong sort paramter'}, status=status.HTTP_400_BAD_REQUEST) tickets = tickets.order_by(sort) else: tickets = tickets.order_by('-created_at') paginator = self.pagination_class() paginated_tickets = paginator.paginate_queryset(tickets, request) tickets_ser = self.serializer_class(instance=paginated_tickets, many=True, context={'request': request}) return paginator.get_paginated_response(tickets_ser.data) class TicketDetailView(generics.RetrieveAPIView): queryset = Ticket.objects.all() serializer_class = TicketSerializer permission_classes = [permissions.IsAuthenticated] def get_queryset(self): user = self.request.user if user.is_staff: return Ticket.objects.all() return Ticket.objects.filter(customer=user) class MessageCreateView(generics.CreateAPIView): queryset = Message.objects.all() serializer_class = MessageSerializer permission_classes = [permissions.IsAuthenticated] def perform_create(self, serializer): ticket = serializer.validated_data.get('ticket') if self.request.user != ticket.customer and not self.request.user.is_staff: raise permissions.PermissionDenied("You are not authorized to send a message to this ticket.") serializer.save(sender=self.request.user) class UpdateTicketStatusView(APIView): permission_classes = [permissions.IsAdminUser] def post(self, request, pk): try: ticket = Ticket.objects.get(pk=pk) except Ticket.DoesNotExist: return Response({"error": "Ticket not found"}, status=404) new_status = request.data.get('status') if new_status not in ['open', 'in_progress', 'resolved', 'closed']: return Response({"error": "Invalid status"}, status=400) ticket.status = new_status ticket.save() return Response({"message": "Ticket status updated successfully"}) class CreateContactUsView(APIView): serializer_class = ContactUsSerializer permission_classes = [permissions.AllowAny] def post(self, request): contact_us_ser = self.serializer_class(data=request.data, context={'request': request}) if contact_us_ser.is_valid(): contact_us_ser.save() return Response(contact_us_ser.data, status=status.HTTP_201_CREATED) else: return Response(contact_us_ser.errors, status=status.HTTP_400_BAD_REQUEST)