Files
ihrm/leave/methods.py

194 lines
7.4 KiB
Python

import calendar
from datetime import datetime, timedelta
from django.apps import apps
from django.db.models import Q
from employee.models import Employee
from horilla.methods import get_horilla_model_class
def calculate_requested_days(
start_date, end_date, start_date_breakdown, end_date_breakdown
):
if start_date == end_date:
if start_date_breakdown == "full_day" and end_date_breakdown == "full_day":
requested_days = 1
else:
requested_days = 0.5
else:
start_days = 0
end_days = 0
if start_date_breakdown != "full_day":
start_days = 0.5
if end_date_breakdown != "full_day":
end_days = 0.5
if start_date_breakdown == "full_day" and end_date_breakdown == "full_day":
requested_days = (end_date - start_date).days + start_days + end_days + 1
else:
if start_date_breakdown == "full_day" or end_date_breakdown == "full_day":
requested_days = (end_date - start_date).days + start_days + end_days
else:
requested_days = (
(end_date - start_date).days + start_days + end_days - 1
)
return requested_days
def leave_requested_dates(start_date, end_date):
"""
:return: this functions returns a list of dates from start date to end date.
"""
request_start_date = start_date
request_end_date = end_date
if request_end_date is None:
request_end_date = start_date
requested_days = request_end_date - request_start_date
requested_dates = []
for i in range(requested_days.days + 1):
date = request_start_date + timedelta(i)
requested_dates.append(date)
return requested_dates
def holiday_dates_list(holidays):
"""
:return: this functions returns a list of all holiday dates.
"""
holiday_dates = []
for holiday in holidays:
holiday_start_date = holiday.start_date
holiday_end_date = holiday.end_date
if holiday_end_date is None:
holiday_end_date = holiday_start_date
holiday_days = holiday_end_date - holiday_start_date
for i in range(holiday_days.days + 1):
date = holiday_start_date + timedelta(i)
holiday_dates.append(date)
return holiday_dates
def company_leave_dates_list(company_leaves, start_date):
"""
:return: This function returns a list of all company leave dates"""
company_leave_dates = []
for company_leave in company_leaves:
year = start_date.year
based_on_week = company_leave.based_on_week
based_on_week_day = company_leave.based_on_week_day
for month in range(1, 13):
if based_on_week != None:
# Set Sunday as the first day of the week
calendar.setfirstweekday(6)
month_calendar = calendar.monthcalendar(year, month)
try:
weeks = month_calendar[int(based_on_week)]
weekdays_in_weeks = [day for day in weeks if day != 0]
for day in weekdays_in_weeks:
date = datetime.strptime(
f"{year}-{month:02}-{day:02}", "%Y-%m-%d"
).date()
if (
date.weekday() == int(based_on_week_day)
and date not in company_leave_dates
):
company_leave_dates.append(date)
except IndexError:
pass
else:
# Set Monday as the first day of the week
calendar.setfirstweekday(0)
month_calendar = calendar.monthcalendar(year, month)
for week in month_calendar:
if week[int(based_on_week_day)] != 0:
date = datetime.strptime(
f"{year}-{month:02}-{week[int(based_on_week_day)]:02}",
"%Y-%m-%d",
).date()
if date not in company_leave_dates:
company_leave_dates.append(date)
return company_leave_dates
def get_leave_day_attendance(employee, comp_id=None):
"""
This function returns a queryset of attendance on leave dates
"""
Attendance = get_horilla_model_class(app_label="attendance", model="attendance")
from leave.models import CompensatoryLeaveRequest
attendances_to_exclude = Attendance.objects.none() # Empty queryset to start with
# Check for compensatory leave requests that are not rejected and not the current one
if (
CompensatoryLeaveRequest.objects.filter(employee_id=employee)
.exclude(Q(id=comp_id) | Q(status="rejected"))
.exists()
):
comp_leave_reqs = CompensatoryLeaveRequest.objects.filter(
employee_id=employee
).exclude(Q(id=comp_id) | Q(status="rejected"))
for req in comp_leave_reqs:
attendances_to_exclude |= req.attendance_id.all()
# Filter holiday attendance excluding the attendances in attendances_to_exclude
holiday_attendance = Attendance.objects.filter(
is_holiday=True, employee_id=employee, attendance_validated=True
).exclude(id__in=attendances_to_exclude.values_list("id", flat=True))
return holiday_attendance
def attendance_days(employee, attendances):
"""
This function returns count of workrecord from the attendance
"""
attendance_days = 0
if apps.is_installed("attendance"):
from attendance.models import WorkRecords
for attendance in attendances:
if WorkRecords.objects.filter(
employee_id=employee, date=attendance.attendance_date
).exists():
work_record_type = (
WorkRecords.objects.filter(
employee_id=employee, date=attendance.attendance_date
)
.first()
.work_record_type
)
if work_record_type == "HDP":
attendance_days += 0.5
elif work_record_type == "FDP":
attendance_days += 1
return attendance_days
def filter_conditional_leave_request(request):
"""
Filters and returns LeaveRequest objects that have been conditionally approved by the previous sequence of approvals.
"""
approval_manager = Employee.objects.filter(employee_user_id=request.user).first()
leave_request_ids = []
if apps.is_installed("leave"):
from leave.models import LeaveRequest, LeaveRequestConditionApproval
multiple_approval_requests = LeaveRequestConditionApproval.objects.filter(
manager_id=approval_manager
)
else:
multiple_approval_requests = None
for instance in multiple_approval_requests:
if instance.sequence > 1:
pre_sequence = instance.sequence - 1
leave_request_id = instance.leave_request_id
instance = LeaveRequestConditionApproval.objects.filter(
leave_request_id=leave_request_id, sequence=pre_sequence
).first()
if instance and instance.is_approved:
leave_request_ids.append(instance.leave_request_id.id)
else:
leave_request_ids.append(instance.leave_request_id.id)
return LeaveRequest.objects.filter(pk__in=leave_request_ids)