from rest_framework import status from rest_framework.viewsets import ModelViewSet from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from rest_framework.filters import SearchFilter, OrderingFilter from django_filters.rest_framework import DjangoFilterBackend from core.paginations.limit_offset import CustomLimitOffsetPagination from apps.clients.models import Client from apps.clients.api.serializers import ( ClientSerializer, ClientCreateSerializer, ClientUpdateSerializer ) from apps.clients.api.permissions import IsClientWorkspaceMember from apps.clients.services.clients import create_client, update_client class ClientViewSet(ModelViewSet): """ API endpoints for managing clients within workspaces. """ permission_classes = [IsAuthenticated, IsClientWorkspaceMember] pagination_class = CustomLimitOffsetPagination filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ("workspace", ) search_fields = ("name", "notes") ordering_fields = ("name", "created_at", "updated_at") ordering = ("-updated_at", "-created_at") def get_queryset(self): """ Returns active clients belonging to workspaces where the current user is an active member. """ if getattr(self, "swagger_fake_view", False) or not self.request.user.is_authenticated: return Client.objects.none() return Client.objects.filter( workspace__memberships__user=self.request.user, workspace__memberships__is_active=True, is_deleted=False ).distinct() def get_serializer_class(self): """ Selects the appropriate serializer based on the request action. """ if self.action == "create": return ClientCreateSerializer elif self.action in ["update", "partial_update"]: return ClientUpdateSerializer return ClientSerializer def create(self, request, *args, **kwargs): """ Creates a new client using the client service. """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) client = create_client( user=request.user, workspace_id=serializer.validated_data["workspace_id"], name=serializer.validated_data["name"], notes=serializer.validated_data.get("notes", "") ) output_serializer = ClientSerializer(client) return Response(output_serializer.data, status=status.HTTP_201_CREATED) def update(self, request, *args, **kwargs): """ Updates an existing client using the client service. """ partial = kwargs.pop("partial", False) client = self.get_object() serializer = self.get_serializer(data=request.data, partial=partial) serializer.is_valid(raise_exception=True) updated_client = update_client( client=client, name=serializer.validated_data.get("name"), notes=serializer.validated_data.get("notes") ) output_serializer = ClientSerializer(updated_client) return Response(output_serializer.data, status=status.HTTP_200_OK) def destroy(self, request, *args, **kwargs): """ Soft deletes a client. """ client = self.get_object() client.is_deleted = True client.save(update_fields=["is_deleted", "updated_at"]) return Response(status=status.HTTP_204_NO_CONTENT)