diff --git a/accessibility/middlewares.py b/accessibility/middlewares.py index de6a05888..f5ff79e96 100644 --- a/accessibility/middlewares.py +++ b/accessibility/middlewares.py @@ -11,9 +11,7 @@ ACCESSIBILITY_CACHE_USER_KEYS = {} def update_accessibility_cache(cache_key, request): - """ - Cache for get all the queryset - """ + """Cache for get all the queryset""" feature_accessible = {} for accessibility, _display in ACCESSBILITY_FEATURE: feature_accessible[accessibility] = check_is_accessible( diff --git a/facedetection/views.py b/facedetection/views.py index d4666e7fe..df56d40bd 100644 --- a/facedetection/views.py +++ b/facedetection/views.py @@ -30,13 +30,13 @@ class FaceDetectionConfigAPIView(APIView): def get_facedetection(self, request): company = self.get_company(request) try: - facedetection = FaceDetection.objects.get(company_id=company) + facedetection = FaceDetection.objects.get_or_create(company_id=company) return facedetection except Exception as e: raise serializers.ValidationError(e) def get(self, request): - serializer = FaceDetectionSerializer(self.get_facedetection(request)) + serializer = FaceDetectionSerializer(self.get_facedetection(request)[0]) return Response(serializer.data, status=status.HTTP_200_OK) @method_decorator( @@ -60,10 +60,9 @@ class FaceDetectionConfigAPIView(APIView): ) def put(self, request): data = request.data - if isinstance(data, QueryDict): - data = data.dict() - data["company_id"] = self.get_company(request).id - serializer = FaceDetectionSerializer(self.get_facedetection(request), data=data) + serializer = FaceDetectionSerializer( + self.get_facedetection(request)[0], data=data + ) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) diff --git a/horilla_api/api_serializers/attendance/serializers.py b/horilla_api/api_serializers/attendance/serializers.py index 853a2c656..71e7332f3 100644 --- a/horilla_api/api_serializers/attendance/serializers.py +++ b/horilla_api/api_serializers/attendance/serializers.py @@ -222,3 +222,9 @@ class UserAttendanceListSerializer(serializers.ModelSerializer): "attendance_clock_out", "attendance_worked_hour", ] + + +class UserAttendanceDetailedSerializer(serializers.ModelSerializer): + class Meta: + model = Attendance + fields = "__all__" diff --git a/horilla_api/api_urls/attendance/urls.py b/horilla_api/api_urls/attendance/urls.py index 00bc37e4b..8a5fc1a9a 100644 --- a/horilla_api/api_urls/attendance/urls.py +++ b/horilla_api/api_urls/attendance/urls.py @@ -57,4 +57,5 @@ urlpatterns = [ path("mail-templates", MailTemplateView.as_view()), path("my-attendance/", UserAttendanceView.as_view()), path("attendance-type-check/", AttendanceTypeAccessCheck.as_view()), + path("my-attendance-detailed//", UserAttendanceDetailedView.as_view()), ] diff --git a/horilla_api/api_views/attendance/views.py b/horilla_api/api_views/attendance/views.py index 631f47edf..570b5a8d5 100644 --- a/horilla_api/api_views/attendance/views.py +++ b/horilla_api/api_views/attendance/views.py @@ -39,6 +39,7 @@ from ...api_serializers.attendance.serializers import ( AttendanceRequestSerializer, AttendanceSerializer, MailTemplateSerializer, + UserAttendanceDetailedSerializer, UserAttendanceListSerializer, ) @@ -722,35 +723,66 @@ class OfflineEmployeesCountView(APIView): permission_classes = [IsAuthenticated] - @method_decorator(permission_required("employee.view_employee")) def get(self, request): - count = ( - EmployeeFilter({"not_in_yet": date.today()}) - .qs.exclude(employee_work_info__isnull=True) - .filter(is_active=True) - .count() + is_manager = ( + EmployeeWorkInformation.objects.filter( + reporting_manager_id=request.user.employee_get + ) + .only("id") + .exists() + ) + + if request.user.has_perm("employee.view_enployee") or is_manager: + count = ( + EmployeeFilter({"not_in_yet": date.today()}) + .qs.exclude(employee_work_info__isnull=True) + .filter(is_active=True) + .count() + ) + return Response({"count": count}, status=200) + return Response( + {"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN ) - return Response({"count": count}, status=200) class OfflineEmployeesListView(APIView): """ - Lists active employees who have not clocked in today, including their leave status. - - Method: - get(request): Retrieves and paginates a list of employees not clocked in today with their leave status. + Li sts active employees who have not clocked in today, including their leave status. """ permission_classes = [IsAuthenticated] - @method_decorator(permission_required("employee.view_employee")) def get(self, request): - queryset = ( - EmployeeFilter({"not_in_yet": date.today()}) + user = request.user + employee = getattr(user, "employee_get", None) + today = date.today() + + # Manager access: get employees reporting to current user + managed_employee_ids = EmployeeWorkInformation.objects.filter( + reporting_manager_id=employee + ).values_list("employee_id", flat=True) + + # Superusers or users with view permission see all employees + if user.has_perm("employee.view_employee"): + base_queryset = Employee.objects.all() + elif managed_employee_ids.exists(): + base_queryset = Employee.objects.filter(id__in=managed_employee_ids) + else: + return Response( + {"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN + ) + + # Apply filtering for offline employees + filtered_qs = ( + EmployeeFilter({"not_in_yet": today}, queryset=base_queryset) .qs.exclude(employee_work_info__isnull=True) .filter(is_active=True) + .select_related("employee_work_info") # optimize joins ) - leave_status = self.get_leave_status(queryset) + + # Get leave status for the filtered employees + leave_status = self.get_leave_status(filtered_qs) + pagenation = PageNumberPagination() page = pagenation.paginate_queryset(leave_status, request) return pagenation.get_paginated_response(page) @@ -978,7 +1010,7 @@ class OfflineEmployeeMailsend(APIView): class UserAttendanceView(APIView): permission_classes = [IsAuthenticated] - serializer_class = UserAttendanceListSerializer + serializer_class = UserAttendanceDetailedSerializer def get(self, request): employee_id = request.user.employee_get.id @@ -1017,3 +1049,16 @@ class AttendanceTypeAccessCheck(APIView): return Response( {"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN ) + + +class UserAttendanceDetailedView(APIView): + permission_classes = [IsAuthenticated] + + def get(self, request, id): + attendance = get_object_or_404(Attendance, pk=id) + if attendance.employee_id == request.user.employee_get: + serializer = UserAttendanceDetailedSerializer(attendance) + return Response(serializer.data, status=200) + return Response( + {"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN + )