Files
GNX-WEB/backEnd/support/views.py
Iliyan Angelov 366f28677a update
2025-11-24 03:52:08 +02:00

217 lines
7.6 KiB
Python

from rest_framework import viewsets, status, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from django.shortcuts import get_object_or_404
from django.db.models import Q
from django.utils import timezone
from .models import (
SupportTicket, TicketStatus, TicketPriority, TicketCategory,
TicketMessage, KnowledgeBaseCategory, KnowledgeBaseArticle, SupportSettings
)
from .serializers import (
SupportTicketSerializer, SupportTicketCreateSerializer,
TicketStatusSerializer, TicketPrioritySerializer, TicketCategorySerializer,
TicketMessageSerializer, TicketStatusCheckSerializer,
KnowledgeBaseCategorySerializer, KnowledgeBaseArticleListSerializer,
KnowledgeBaseArticleDetailSerializer, SupportSettingsSerializer
)
class SupportTicketViewSet(viewsets.ModelViewSet):
"""
ViewSet for managing support tickets.
Public endpoint for creating tickets and checking status.
"""
queryset = SupportTicket.objects.all()
permission_classes = [AllowAny]
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['ticket_number', 'title', 'user_email', 'user_name']
ordering_fields = ['created_at', 'updated_at', 'priority']
ordering = ['-created_at']
def get_serializer_class(self):
if self.action == 'create':
return SupportTicketCreateSerializer
return SupportTicketSerializer
@action(detail=False, methods=['post'], url_path='check-status')
def check_status(self, request):
"""
Check the status of a ticket by ticket number.
POST /api/support/tickets/check-status/
Body: {"ticket_number": "TKT-20231015-XXXXX"}
"""
serializer = TicketStatusCheckSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
ticket_number = serializer.validated_data['ticket_number']
try:
ticket = SupportTicket.objects.get(ticket_number=ticket_number)
ticket_serializer = SupportTicketSerializer(ticket)
return Response(ticket_serializer.data)
except SupportTicket.DoesNotExist:
return Response(
{'error': 'Ticket not found. Please check your ticket number.'},
status=status.HTTP_404_NOT_FOUND
)
@action(detail=True, methods=['post'], url_path='add-message')
def add_message(self, request, pk=None):
"""
Add a message to a ticket.
POST /api/support/tickets/{id}/add-message/
Body: {
"content": "Message content",
"author_name": "User Name",
"author_email": "user@example.com"
}
"""
ticket = self.get_object()
message_data = {
'ticket': ticket.id,
'content': request.data.get('content'),
'author_name': request.data.get('author_name', ticket.user_name),
'author_email': request.data.get('author_email', ticket.user_email),
'message_type': 'user_message'
}
serializer = TicketMessageSerializer(data=message_data)
serializer.is_valid(raise_exception=True)
serializer.save()
# Update ticket's last activity
ticket.last_activity = timezone.now()
ticket.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
class TicketCategoryViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for ticket categories.
Public read-only access to categories.
"""
queryset = TicketCategory.objects.filter(is_active=True)
serializer_class = TicketCategorySerializer
permission_classes = [AllowAny]
class TicketStatusViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for ticket statuses.
Public read-only access to statuses.
"""
queryset = TicketStatus.objects.filter(is_active=True)
serializer_class = TicketStatusSerializer
permission_classes = [AllowAny]
class TicketPriorityViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for ticket priorities.
Public read-only access to priorities.
"""
queryset = TicketPriority.objects.filter(is_active=True)
serializer_class = TicketPrioritySerializer
permission_classes = [AllowAny]
class KnowledgeBaseCategoryViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for knowledge base categories.
Public read-only access.
"""
queryset = KnowledgeBaseCategory.objects.filter(is_active=True)
serializer_class = KnowledgeBaseCategorySerializer
permission_classes = [AllowAny]
lookup_field = 'slug'
class KnowledgeBaseArticleViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for knowledge base articles.
Public read-only access to published articles.
"""
queryset = KnowledgeBaseArticle.objects.filter(is_published=True)
permission_classes = [AllowAny]
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['title', 'content', 'summary', 'keywords']
ordering_fields = ['created_at', 'view_count', 'helpful_count']
ordering = ['-created_at']
lookup_field = 'slug'
def get_serializer_class(self):
if self.action == 'retrieve':
return KnowledgeBaseArticleDetailSerializer
return KnowledgeBaseArticleListSerializer
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
# Increment view count
instance.view_count += 1
instance.save(update_fields=['view_count'])
serializer = self.get_serializer(instance)
return Response(serializer.data)
@action(detail=True, methods=['post'], url_path='mark-helpful')
def mark_helpful(self, request, slug=None):
"""
Mark an article as helpful.
POST /api/support/knowledge-base/{slug}/mark-helpful/
Body: {"helpful": true/false}
"""
article = self.get_object()
is_helpful = request.data.get('helpful', True)
if is_helpful:
article.helpful_count += 1
else:
article.not_helpful_count += 1
article.save()
return Response({
'helpful_count': article.helpful_count,
'not_helpful_count': article.not_helpful_count
})
@action(detail=False, methods=['get'], url_path='featured')
def featured(self, request):
"""
Get featured articles.
GET /api/support/knowledge-base/featured/
"""
featured_articles = self.queryset.filter(is_featured=True)[:6]
serializer = self.get_serializer(featured_articles, many=True)
return Response(serializer.data)
@action(detail=False, methods=['get'], url_path='by-category/(?P<category_slug>[^/.]+)')
def by_category(self, request, category_slug=None):
"""
Get articles by category slug.
GET /api/support/knowledge-base/by-category/{category_slug}/
"""
articles = self.queryset.filter(category__slug=category_slug)
page = self.paginate_queryset(articles)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(articles, many=True)
return Response(serializer.data)
class SupportSettingsViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for support settings.
Public read-only access to active settings.
"""
queryset = SupportSettings.objects.filter(is_active=True)
serializer_class = SupportSettingsSerializer
permission_classes = [AllowAny]
lookup_field = 'setting_name'