238 lines
7.8 KiB
Python
238 lines
7.8 KiB
Python
"""
|
|
Solution (Knowledge Base) Views
|
|
"""
|
|
|
|
from drf_spectacular.utils import OpenApiParameter, extend_schema, inline_serializer
|
|
from rest_framework import serializers, status
|
|
from rest_framework.pagination import LimitOffsetPagination
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
|
|
from cases.models import Solution
|
|
from cases.solution_serializers import (
|
|
SolutionCreateUpdateSerializer,
|
|
SolutionDetailSerializer,
|
|
SolutionSerializer,
|
|
)
|
|
|
|
|
|
class SolutionListView(APIView, LimitOffsetPagination):
|
|
"""
|
|
List and create solutions (Knowledge Base)
|
|
"""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="List all solutions with filters",
|
|
parameters=[
|
|
OpenApiParameter(
|
|
"status", str, description="Filter by status (draft/reviewed/approved)"
|
|
),
|
|
OpenApiParameter(
|
|
"is_published", bool, description="Filter by published status"
|
|
),
|
|
OpenApiParameter(
|
|
"search", str, description="Search in title and description"
|
|
),
|
|
],
|
|
responses={200: SolutionSerializer(many=True)},
|
|
)
|
|
def get(self, request):
|
|
"""List solutions with filters"""
|
|
queryset = Solution.objects.filter(org=request.profile.org).order_by(
|
|
"-created_at"
|
|
)
|
|
|
|
# Filters
|
|
status_filter = request.query_params.get("status")
|
|
is_published = request.query_params.get("is_published")
|
|
search = request.query_params.get("search")
|
|
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
if is_published is not None:
|
|
queryset = queryset.filter(is_published=is_published.lower() == "true")
|
|
|
|
if search:
|
|
queryset = queryset.filter(title__icontains=search) | queryset.filter(
|
|
description__icontains=search
|
|
)
|
|
|
|
# Paginate
|
|
results = self.paginate_queryset(queryset, request, view=self)
|
|
serializer = SolutionSerializer(results, many=True)
|
|
|
|
return self.get_paginated_response(serializer.data)
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="Create a new solution",
|
|
request=SolutionCreateUpdateSerializer,
|
|
responses={201: SolutionSerializer},
|
|
)
|
|
def post(self, request):
|
|
"""Create a new solution"""
|
|
serializer = SolutionCreateUpdateSerializer(data=request.data)
|
|
|
|
if serializer.is_valid():
|
|
solution = serializer.save(org=request.profile.org, created_by=request.user)
|
|
|
|
response_serializer = SolutionSerializer(solution)
|
|
return Response(response_serializer.data, status=status.HTTP_201_CREATED)
|
|
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
|
class SolutionDetailView(APIView):
|
|
"""
|
|
Get, update, or delete a solution
|
|
"""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="Get solution details",
|
|
responses={200: SolutionDetailSerializer},
|
|
)
|
|
def get(self, request, pk):
|
|
"""Get solution details"""
|
|
try:
|
|
solution = Solution.objects.get(pk=pk, org=request.profile.org)
|
|
serializer = SolutionDetailSerializer(solution)
|
|
return Response(serializer.data)
|
|
except Solution.DoesNotExist:
|
|
return Response(
|
|
{"error": "Solution not found"}, status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="Update solution",
|
|
request=SolutionCreateUpdateSerializer,
|
|
responses={200: SolutionSerializer},
|
|
)
|
|
def put(self, request, pk):
|
|
"""Update solution"""
|
|
try:
|
|
solution = Solution.objects.get(pk=pk, org=request.profile.org)
|
|
|
|
serializer = SolutionCreateUpdateSerializer(solution, data=request.data)
|
|
if serializer.is_valid():
|
|
solution = serializer.save(updated_by=request.user)
|
|
response_serializer = SolutionSerializer(solution)
|
|
return Response(response_serializer.data)
|
|
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
except Solution.DoesNotExist:
|
|
return Response(
|
|
{"error": "Solution not found"}, status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="Partially update solution",
|
|
request=SolutionCreateUpdateSerializer,
|
|
responses={200: SolutionSerializer},
|
|
)
|
|
def patch(self, request, pk):
|
|
"""Partially update solution"""
|
|
try:
|
|
solution = Solution.objects.get(pk=pk, org=request.profile.org)
|
|
|
|
serializer = SolutionCreateUpdateSerializer(
|
|
solution, data=request.data, partial=True
|
|
)
|
|
if serializer.is_valid():
|
|
solution = serializer.save(updated_by=request.user)
|
|
response_serializer = SolutionSerializer(solution)
|
|
return Response(response_serializer.data)
|
|
|
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
except Solution.DoesNotExist:
|
|
return Response(
|
|
{"error": "Solution not found"}, status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="Delete solution",
|
|
responses={204: None},
|
|
)
|
|
def delete(self, request, pk):
|
|
"""Delete solution"""
|
|
try:
|
|
solution = Solution.objects.get(pk=pk, org=request.profile.org)
|
|
solution.delete()
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
except Solution.DoesNotExist:
|
|
return Response(
|
|
{"error": "Solution not found"}, status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
|
|
class SolutionPublishView(APIView):
|
|
"""
|
|
Publish or unpublish a solution
|
|
"""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="Publish an approved solution",
|
|
request=None,
|
|
responses={200: SolutionSerializer},
|
|
)
|
|
def post(self, request, pk):
|
|
"""Publish solution"""
|
|
try:
|
|
solution = Solution.objects.get(pk=pk, org=request.profile.org)
|
|
|
|
if solution.status != "approved":
|
|
return Response(
|
|
{
|
|
"error": "Only approved solutions can be published. Please approve it first."
|
|
},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
|
|
solution.publish()
|
|
serializer = SolutionSerializer(solution)
|
|
return Response(serializer.data)
|
|
|
|
except Solution.DoesNotExist:
|
|
return Response(
|
|
{"error": "Solution not found"}, status=status.HTTP_404_NOT_FOUND
|
|
)
|
|
|
|
|
|
class SolutionUnpublishView(APIView):
|
|
"""
|
|
Unpublish a solution
|
|
"""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
@extend_schema(
|
|
tags=["Solutions (Knowledge Base)"],
|
|
description="Unpublish a solution",
|
|
request=None,
|
|
responses={200: SolutionSerializer},
|
|
)
|
|
def post(self, request, pk):
|
|
"""Unpublish solution"""
|
|
try:
|
|
solution = Solution.objects.get(pk=pk, org=request.profile.org)
|
|
solution.unpublish()
|
|
serializer = SolutionSerializer(solution)
|
|
return Response(serializer.data)
|
|
|
|
except Solution.DoesNotExist:
|
|
return Response(
|
|
{"error": "Solution not found"}, status=status.HTTP_404_NOT_FOUND
|
|
)
|