[UPDT] ATTENDANCE: Attendance api updates

This commit is contained in:
Horilla
2025-08-12 10:17:52 +05:30
parent 5ea912cbc4
commit 5446f9542e
5 changed files with 74 additions and 25 deletions

View File

@@ -11,9 +11,7 @@ ACCESSIBILITY_CACHE_USER_KEYS = {}
def update_accessibility_cache(cache_key, request): def update_accessibility_cache(cache_key, request):
""" """Cache for get all the queryset"""
Cache for get all the queryset
"""
feature_accessible = {} feature_accessible = {}
for accessibility, _display in ACCESSBILITY_FEATURE: for accessibility, _display in ACCESSBILITY_FEATURE:
feature_accessible[accessibility] = check_is_accessible( feature_accessible[accessibility] = check_is_accessible(

View File

@@ -30,13 +30,13 @@ class FaceDetectionConfigAPIView(APIView):
def get_facedetection(self, request): def get_facedetection(self, request):
company = self.get_company(request) company = self.get_company(request)
try: try:
facedetection = FaceDetection.objects.get(company_id=company) facedetection = FaceDetection.objects.get_or_create(company_id=company)
return facedetection return facedetection
except Exception as e: except Exception as e:
raise serializers.ValidationError(e) raise serializers.ValidationError(e)
def get(self, request): 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) return Response(serializer.data, status=status.HTTP_200_OK)
@method_decorator( @method_decorator(
@@ -60,10 +60,9 @@ class FaceDetectionConfigAPIView(APIView):
) )
def put(self, request): def put(self, request):
data = request.data data = request.data
if isinstance(data, QueryDict): serializer = FaceDetectionSerializer(
data = data.dict() self.get_facedetection(request)[0], data=data
data["company_id"] = self.get_company(request).id )
serializer = FaceDetectionSerializer(self.get_facedetection(request), data=data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.data, status=status.HTTP_200_OK)

View File

@@ -222,3 +222,9 @@ class UserAttendanceListSerializer(serializers.ModelSerializer):
"attendance_clock_out", "attendance_clock_out",
"attendance_worked_hour", "attendance_worked_hour",
] ]
class UserAttendanceDetailedSerializer(serializers.ModelSerializer):
class Meta:
model = Attendance
fields = "__all__"

View File

@@ -57,4 +57,5 @@ urlpatterns = [
path("mail-templates", MailTemplateView.as_view()), path("mail-templates", MailTemplateView.as_view()),
path("my-attendance/", UserAttendanceView.as_view()), path("my-attendance/", UserAttendanceView.as_view()),
path("attendance-type-check/", AttendanceTypeAccessCheck.as_view()), path("attendance-type-check/", AttendanceTypeAccessCheck.as_view()),
path("my-attendance-detailed/<int:id>/", UserAttendanceDetailedView.as_view()),
] ]

View File

@@ -39,6 +39,7 @@ from ...api_serializers.attendance.serializers import (
AttendanceRequestSerializer, AttendanceRequestSerializer,
AttendanceSerializer, AttendanceSerializer,
MailTemplateSerializer, MailTemplateSerializer,
UserAttendanceDetailedSerializer,
UserAttendanceListSerializer, UserAttendanceListSerializer,
) )
@@ -722,35 +723,66 @@ class OfflineEmployeesCountView(APIView):
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@method_decorator(permission_required("employee.view_employee"))
def get(self, request): def get(self, request):
count = ( is_manager = (
EmployeeFilter({"not_in_yet": date.today()}) EmployeeWorkInformation.objects.filter(
.qs.exclude(employee_work_info__isnull=True) reporting_manager_id=request.user.employee_get
.filter(is_active=True) )
.count() .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): class OfflineEmployeesListView(APIView):
""" """
Lists active employees who have not clocked in today, including their leave status. Li sts 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.
""" """
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@method_decorator(permission_required("employee.view_employee"))
def get(self, request): def get(self, request):
queryset = ( user = request.user
EmployeeFilter({"not_in_yet": date.today()}) 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) .qs.exclude(employee_work_info__isnull=True)
.filter(is_active=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() pagenation = PageNumberPagination()
page = pagenation.paginate_queryset(leave_status, request) page = pagenation.paginate_queryset(leave_status, request)
return pagenation.get_paginated_response(page) return pagenation.get_paginated_response(page)
@@ -978,7 +1010,7 @@ class OfflineEmployeeMailsend(APIView):
class UserAttendanceView(APIView): class UserAttendanceView(APIView):
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
serializer_class = UserAttendanceListSerializer serializer_class = UserAttendanceDetailedSerializer
def get(self, request): def get(self, request):
employee_id = request.user.employee_get.id employee_id = request.user.employee_get.id
@@ -1017,3 +1049,16 @@ class AttendanceTypeAccessCheck(APIView):
return Response( return Response(
{"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN {"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
)