Files
ihrm/attendance/middleware.py

80 lines
3.1 KiB
Python
Raw Normal View History

"""
Middleware to automatically trigger employee clock-out based on shift schedules
"""
from datetime import datetime, timedelta
from django.utils import timezone
from django.utils.deprecation import MiddlewareMixin
from attendance.methods.utils import Request
class AttendanceMiddleware(MiddlewareMixin):
"""
This middleware checks for employees who haven't clocked out by the end of their
scheduled shift and automatically performs the clock-out action if the auto punch-out
is enabled for their shift. It processes this during each request.
"""
def process_request(self, request):
"""
Triggers the `trigger_function` on each request.
"""
self.trigger_function()
def trigger_function(self):
"""
Retrieves shift schedules with auto punch-out enabled and checks if there are
any attendance activities that haven't been clocked out. If the scheduled
auto punch-out time has passed, the function attempts to clock out the employee
automatically by invoking the `clock_out` function.
"""
from attendance.models import Attendance, AttendanceActivity
from attendance.views.clock_in_out import clock_out
from base.models import EmployeeShiftSchedule
automatic_check_out_shifts = EmployeeShiftSchedule.objects.filter(
is_auto_punch_out_enabled=True
)
for shift_schedule in automatic_check_out_shifts:
activities = AttendanceActivity.objects.filter(
shift_day=shift_schedule.day,
clock_out_date=None,
clock_out=None,
).order_by("-created_at")
for activity in activities:
attendance = Attendance.objects.filter(
employee_id=activity.employee_id,
attendance_clock_out=None,
attendance_clock_out_date=None,
shift_id=shift_schedule.shift_id,
attendance_day=shift_schedule.day,
attendance_date=activity.attendance_date,
).first()
if attendance:
date = activity.attendance_date
if shift_schedule.is_night_shift:
date += timedelta(days=1)
combined_datetime = timezone.make_aware(
datetime.combine(date, shift_schedule.auto_punch_out_time)
)
current_time = timezone.now()
if combined_datetime < current_time:
try:
clock_out(
Request(
user=attendance.employee_id.employee_user_id,
date=date,
time=shift_schedule.auto_punch_out_time,
datetime=combined_datetime,
)
)
except Exception as e:
print(f"{e}")