diff --git a/horilla_api/api_serializers/helpdesk/__init__.py b/horilla_api/api_serializers/helpdesk/__init__.py index 8dd2c6d2f..af6501367 100644 --- a/horilla_api/api_serializers/helpdesk/__init__.py +++ b/horilla_api/api_serializers/helpdesk/__init__.py @@ -1,4 +1,3 @@ """ horilla_api/api_serializers/helpdesk/__init__.py """ - diff --git a/horilla_api/api_serializers/helpdesk/serializers.py b/horilla_api/api_serializers/helpdesk/serializers.py index 32d727cd8..377e3a9b9 100644 --- a/horilla_api/api_serializers/helpdesk/serializers.py +++ b/horilla_api/api_serializers/helpdesk/serializers.py @@ -3,18 +3,19 @@ horilla_api/api_serializers/helpdesk/serializers.py """ from rest_framework import serializers + +from base.models import Tags +from employee.models import Employee from helpdesk.models import ( - Ticket, - TicketType, FAQ, - FAQCategory, - Comment, Attachment, ClaimRequest, + Comment, DepartmentManager, + FAQCategory, + Ticket, + TicketType, ) -from employee.models import Employee -from base.models import Tags class TicketTypeSerializer(serializers.ModelSerializer): @@ -73,7 +74,10 @@ class DepartmentManagerSerializer(serializers.ModelSerializer): class CommentSerializer(serializers.ModelSerializer): employee_id = serializers.SerializerMethodField() employee_id_write = serializers.PrimaryKeyRelatedField( - queryset=Employee.objects.all(), source="employee_id", write_only=True, required=False + queryset=Employee.objects.all(), + source="employee_id", + write_only=True, + required=False, ) ticket_id = serializers.PrimaryKeyRelatedField( queryset=Ticket.objects.all(), source="ticket", write_only=True @@ -99,7 +103,10 @@ class AttachmentSerializer(serializers.ModelSerializer): queryset=Ticket.objects.all(), source="ticket", write_only=True, required=False ) comment_id = serializers.PrimaryKeyRelatedField( - queryset=Comment.objects.all(), source="comment", write_only=True, required=False + queryset=Comment.objects.all(), + source="comment", + write_only=True, + required=False, ) class Meta: @@ -143,7 +150,10 @@ class ClaimRequestSerializer(serializers.ModelSerializer): class TicketSerializer(serializers.ModelSerializer): employee_id = serializers.SerializerMethodField() employee_id_write = serializers.PrimaryKeyRelatedField( - queryset=Employee.objects.all(), source="employee_id", write_only=True, required=False + queryset=Employee.objects.all(), + source="employee_id", + write_only=True, + required=False, ) ticket_type = TicketTypeSerializer(read_only=True) ticket_type_id = serializers.PrimaryKeyRelatedField( @@ -151,11 +161,19 @@ class TicketSerializer(serializers.ModelSerializer): ) assigned_to = serializers.SerializerMethodField() assigned_to_ids = serializers.PrimaryKeyRelatedField( - queryset=Employee.objects.all(), many=True, source="assigned_to", write_only=True, required=False + queryset=Employee.objects.all(), + many=True, + source="assigned_to", + write_only=True, + required=False, ) tags = serializers.SerializerMethodField() tags_ids = serializers.PrimaryKeyRelatedField( - queryset=Tags.objects.all(), many=True, source="tags", write_only=True, required=False + queryset=Tags.objects.all(), + many=True, + source="tags", + write_only=True, + required=False, ) raised_on_display = serializers.SerializerMethodField() comments = CommentSerializer(many=True, read_only=True) @@ -165,8 +183,8 @@ class TicketSerializer(serializers.ModelSerializer): model = Ticket fields = "__all__" extra_kwargs = { - 'assigned_to': {'read_only': True}, - 'tags': {'read_only': True}, + "assigned_to": {"read_only": True}, + "tags": {"read_only": True}, } def get_employee_id(self, obj): @@ -202,4 +220,3 @@ class TicketSerializer(serializers.ModelSerializer): return obj.get_raised_on() except: return obj.raised_on - diff --git a/horilla_api/api_urls/helpdesk/__init__.py b/horilla_api/api_urls/helpdesk/__init__.py index bac555350..fee16613f 100644 --- a/horilla_api/api_urls/helpdesk/__init__.py +++ b/horilla_api/api_urls/helpdesk/__init__.py @@ -1,4 +1,3 @@ """ horilla_api/api_urls/helpdesk/__init__.py """ - diff --git a/horilla_api/api_urls/helpdesk/urls.py b/horilla_api/api_urls/helpdesk/urls.py index c0cfbe1a6..902c7d71c 100644 --- a/horilla_api/api_urls/helpdesk/urls.py +++ b/horilla_api/api_urls/helpdesk/urls.py @@ -3,45 +3,43 @@ horilla_api/api_urls/helpdesk/urls.py """ from django.urls import path + from horilla_api.api_views.helpdesk.views import * urlpatterns = [ # Ticket Type URLs path("ticket-type/", TicketTypeGetCreateAPIView.as_view()), path("ticket-type//", TicketTypeGetUpdateDeleteAPIView.as_view()), - # FAQ Category URLs path("faq-category/", FAQCategoryGetCreateAPIView.as_view()), path("faq-category//", FAQCategoryGetUpdateDeleteAPIView.as_view()), - # FAQ URLs path("faq/", FAQGetCreateAPIView.as_view()), path("faq//", FAQGetUpdateDeleteAPIView.as_view()), path("faq/category//", FAQGetCreateAPIView.as_view()), - # Ticket URLs path("ticket/", TicketGetCreateAPIView.as_view()), path("ticket//", TicketGetUpdateDeleteAPIView.as_view()), path("ticket//status/", TicketChangeStatusAPIView.as_view()), path("ticket//archive/", TicketArchiveAPIView.as_view()), - # Comment URLs path("ticket//comment/", CommentGetCreateAPIView.as_view()), path("comment//", CommentGetUpdateDeleteAPIView.as_view()), - # Attachment URLs path("ticket//attachment/", AttachmentGetCreateAPIView.as_view()), path("comment//attachment/", AttachmentGetCreateAPIView.as_view()), path("attachment//", AttachmentGetDeleteAPIView.as_view()), - # Claim Request URLs path("claim-request/", ClaimRequestGetCreateAPIView.as_view()), - path("ticket//claim-request/", ClaimRequestGetCreateAPIView.as_view()), + path( + "ticket//claim-request/", ClaimRequestGetCreateAPIView.as_view() + ), path("claim-request//approve/", ClaimRequestApproveAPIView.as_view()), path("claim-request//reject/", ClaimRequestRejectAPIView.as_view()), - # Department Manager URLs path("department-manager/", DepartmentManagerGetCreateAPIView.as_view()), - path("department-manager//", DepartmentManagerGetUpdateDeleteAPIView.as_view()), + path( + "department-manager//", + DepartmentManagerGetUpdateDeleteAPIView.as_view(), + ), ] - diff --git a/horilla_api/api_views/asset/views.py b/horilla_api/api_views/asset/views.py index 027abf20e..bbaa67de8 100644 --- a/horilla_api/api_views/asset/views.py +++ b/horilla_api/api_views/asset/views.py @@ -19,6 +19,7 @@ class AssetAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = AssetFilter + queryset = Asset.objects.all() def get_asset(self, pk): try: @@ -63,6 +64,7 @@ class AssetCategoryAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = AssetCategoryFilter + queryset = AssetCategory.objects.all() def get_asset_category(self, pk): try: diff --git a/horilla_api/api_views/base/views.py b/horilla_api/api_views/base/views.py index ef75e5e8d..2169021e0 100644 --- a/horilla_api/api_views/base/views.py +++ b/horilla_api/api_views/base/views.py @@ -921,6 +921,7 @@ class ShiftRequestView(APIView): filter_backends = [DjangoFilterBackend] filterset_class = ShiftRequestFilter permission_classes = [IsAuthenticated] + queryset = ShiftRequest.objects.all() def get_queryset(self, request=None): # Handle schema generation for DRF-YASG diff --git a/horilla_api/api_views/employee/views.py b/horilla_api/api_views/employee/views.py index d7ba5f0f1..43aa5e076 100644 --- a/horilla_api/api_views/employee/views.py +++ b/horilla_api/api_views/employee/views.py @@ -98,6 +98,7 @@ class EmployeeAPIView(APIView): filter_backends = [DjangoFilterBackend] filterset_class = EmployeeFilter permission_classes = [IsAuthenticated] + queryset = Employee.objects.all() def get(self, request, pk): user = request.user diff --git a/horilla_api/api_views/helpdesk/__init__.py b/horilla_api/api_views/helpdesk/__init__.py index 9c86b2368..e286dc42f 100644 --- a/horilla_api/api_views/helpdesk/__init__.py +++ b/horilla_api/api_views/helpdesk/__init__.py @@ -1,4 +1,3 @@ """ horilla_api/api_views/helpdesk/__init__.py """ - diff --git a/horilla_api/api_views/helpdesk/views.py b/horilla_api/api_views/helpdesk/views.py index 691ec5d9a..4172439c7 100644 --- a/horilla_api/api_views/helpdesk/views.py +++ b/horilla_api/api_views/helpdesk/views.py @@ -2,44 +2,45 @@ horilla_api/api_views/helpdesk/views.py """ -from rest_framework.views import APIView -from rest_framework.permissions import IsAuthenticated -from rest_framework.response import Response -from rest_framework import status -from rest_framework.pagination import PageNumberPagination -from django_filters.rest_framework import DjangoFilterBackend -from django.shortcuts import get_object_or_404 -from django.http import Http404 from django.contrib.auth.models import AnonymousUser from django.db.models import Q +from django.http import Http404 +from django.shortcuts import get_object_or_404 +from django_filters.rest_framework import DjangoFilterBackend +from rest_framework import status +from rest_framework.pagination import PageNumberPagination +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework.views import APIView -from horilla_api.api_serializers.helpdesk.serializers import ( - TicketSerializer, - TicketTypeSerializer, - FAQSerializer, - FAQCategorySerializer, - CommentSerializer, - AttachmentSerializer, - ClaimRequestSerializer, - DepartmentManagerSerializer, -) +from base.methods import filtersubordinates +from helpdesk.filter import FAQCategoryFilter, FAQFilter, TicketFilter from helpdesk.models import ( - Ticket, - TicketType, FAQ, - FAQCategory, - Comment, Attachment, ClaimRequest, + Comment, DepartmentManager, + FAQCategory, + Ticket, + TicketType, ) -from helpdesk.filter import TicketFilter, FAQFilter, FAQCategoryFilter -from ...api_methods.base.methods import groupby_queryset, permission_based_queryset +from horilla_api.api_serializers.helpdesk.serializers import ( + AttachmentSerializer, + ClaimRequestSerializer, + CommentSerializer, + DepartmentManagerSerializer, + FAQCategorySerializer, + FAQSerializer, + TicketSerializer, + TicketTypeSerializer, +) + from ...api_decorators.base.decorators import ( manager_permission_required, permission_required, ) -from base.methods import filtersubordinates +from ...api_methods.base.methods import groupby_queryset, permission_based_queryset def object_check(cls, pk): @@ -54,10 +55,11 @@ def object_check(cls, pk): class TicketTypeGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] + queryset = TicketType.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG - if getattr(self, 'swagger_fake_view', False): + if getattr(self, "swagger_fake_view", False): return TicketType.objects.none() return TicketType.objects.all() @@ -115,10 +117,11 @@ class FAQCategoryGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = FAQCategoryFilter + queryset = FAQCategory.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG - if getattr(self, 'swagger_fake_view', False): + if getattr(self, "swagger_fake_view", False): return FAQCategory.objects.none() return FAQCategory.objects.all() @@ -177,10 +180,11 @@ class FAQGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = FAQFilter + queryset = FAQ.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG - if getattr(self, 'swagger_fake_view', False): + if getattr(self, "swagger_fake_view", False): return FAQ.objects.none() return FAQ.objects.all() @@ -242,10 +246,11 @@ class TicketGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = TicketFilter + queryset = Ticket.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG - if getattr(self, 'swagger_fake_view', False): + if getattr(self, "swagger_fake_view", False): return Ticket.objects.none() if not self.request.user.is_authenticated: return Ticket.objects.none() @@ -270,12 +275,18 @@ class TicketGetCreateAPIView(APIView): def post(self, request): # Set employee_id from request user if not provided data = request.data.copy() - if not data.get("employee_id_write") and not data.get("employee_id") and request.user.is_authenticated: + if ( + not data.get("employee_id_write") + and not data.get("employee_id") + and request.user.is_authenticated + ): data["employee_id_write"] = request.user.employee_get.id serializer = TicketSerializer(data=data) if serializer.is_valid(): ticket = serializer.save() - return Response(TicketSerializer(ticket).data, status=status.HTTP_201_CREATED) + return Response( + TicketSerializer(ticket).data, status=status.HTTP_201_CREATED + ) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -288,9 +299,11 @@ class TicketGetUpdateDeleteAPIView(APIView): return Response({"error": "Ticket not found"}, status=404) # Check permissions user = request.user - if not (user.has_perm("helpdesk.view_ticket") or - ticket.employee_id == user.employee_get or - ticket.assigned_to.filter(id=user.employee_get.id).exists()): + if not ( + user.has_perm("helpdesk.view_ticket") + or ticket.employee_id == user.employee_get + or ticket.assigned_to.filter(id=user.employee_get.id).exists() + ): return Response({"error": "Permission denied"}, status=403) serializer = TicketSerializer(ticket) return Response(serializer.data, status=200) @@ -327,11 +340,14 @@ class TicketChangeStatusAPIView(APIView): if ticket is None: return Response({"error": "Ticket not found"}, status=404) status_value = request.data.get("status") - if status_value not in [choice[0] for choice in Ticket._meta.get_field("status").choices]: + if status_value not in [ + choice[0] for choice in Ticket._meta.get_field("status").choices + ]: return Response({"error": "Invalid status"}, status=400) ticket.status = status_value if status_value == "resolved": from datetime import date + ticket.resolved_date = date.today() ticket.save() return Response(TicketSerializer(ticket).data, status=200) @@ -370,12 +386,18 @@ class CommentGetCreateAPIView(APIView): return Response({"error": "Ticket not found"}, status=404) data = request.data.copy() data["ticket_id"] = ticket_id - if not data.get("employee_id_write") and not data.get("employee_id") and request.user.is_authenticated: + if ( + not data.get("employee_id_write") + and not data.get("employee_id") + and request.user.is_authenticated + ): data["employee_id_write"] = request.user.employee_get.id serializer = CommentSerializer(data=data) if serializer.is_valid(): comment = serializer.save() - return Response(CommentSerializer(comment).data, status=status.HTTP_201_CREATED) + return Response( + CommentSerializer(comment).data, status=status.HTTP_201_CREATED + ) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -407,7 +429,10 @@ class CommentGetUpdateDeleteAPIView(APIView): if comment is None: return Response({"error": "Comment not found"}, status=404) # Check if user owns the comment or has permission - if comment.employee_id != request.user.employee_get and not request.user.has_perm("helpdesk.delete_comment"): + if ( + comment.employee_id != request.user.employee_get + and not request.user.has_perm("helpdesk.delete_comment") + ): return Response({"error": "Permission denied"}, status=403) try: comment.delete() @@ -436,7 +461,9 @@ class AttachmentGetCreateAPIView(APIView): serializer = AttachmentSerializer(data=request.data) if serializer.is_valid(): attachment = serializer.save() - return Response(AttachmentSerializer(attachment).data, status=status.HTTP_201_CREATED) + return Response( + AttachmentSerializer(attachment).data, status=status.HTTP_201_CREATED + ) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -479,7 +506,10 @@ class ClaimRequestGetCreateAPIView(APIView): serializer = ClaimRequestSerializer(data=request.data) if serializer.is_valid(): claim_request = serializer.save() - return Response(ClaimRequestSerializer(claim_request).data, status=status.HTTP_201_CREATED) + return Response( + ClaimRequestSerializer(claim_request).data, + status=status.HTTP_201_CREATED, + ) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -520,7 +550,7 @@ class DepartmentManagerGetCreateAPIView(APIView): def get_queryset(self): # Handle schema generation for DRF-YASG - if getattr(self, 'swagger_fake_view', False): + if getattr(self, "swagger_fake_view", False): return DepartmentManager.objects.none() return DepartmentManager.objects.all() @@ -571,4 +601,3 @@ class DepartmentManagerGetUpdateDeleteAPIView(APIView): return Response(status=status.HTTP_204_NO_CONTENT) except Exception as e: return Response({"error": str(e)}, status=400) - diff --git a/horilla_api/api_views/leave/views.py b/horilla_api/api_views/leave/views.py index e606c5348..91b725938 100644 --- a/horilla_api/api_views/leave/views.py +++ b/horilla_api/api_views/leave/views.py @@ -38,6 +38,7 @@ class EmployeeLeaveRequestGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = UserLeaveRequestFilter + queryset = LeaveRequest.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG @@ -151,6 +152,7 @@ class LeaveTypeGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = LeaveTypeFilter + queryset = LeaveType.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG @@ -223,6 +225,7 @@ class LeaveAllocationRequestGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = LeaveAllocationRequestFilter + queryset = LeaveAllocationRequest.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG @@ -330,6 +333,7 @@ class AssignLeaveGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = AssignedLeaveFilter + queryset = AvailableLeave.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG @@ -441,6 +445,7 @@ class LeaveRequestGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = LeaveRequestFilter + queryset = LeaveRequest.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG @@ -970,6 +975,7 @@ class EmployeeLeaveAllocationGetCreateAPIView(APIView): permission_classes = [IsAuthenticated] filter_backends = [DjangoFilterBackend] filterset_class = LeaveAllocationRequestFilter + queryset = LeaveAllocationRequest.objects.all() def get_queryset(self): # Handle schema generation for DRF-YASG