""" filters.py This page is used to register filter for employee models """ import django import django_filters from django import forms from django.utils.translation import gettext as _ from django_filters import CharFilter # from attendance.models import Attendance from accessibility.methods import check_is_accessible from accessibility.models import DefaultAccessibility from base.methods import filtersubordinatesemployeemodel from employee.models import DisciplinaryAction, Employee, Policy from horilla.filters import FilterSet, HorillaFilterSet, filter_by_name from horilla.horilla_middlewares import _thread_locals from horilla_documents.models import Document from horilla_views.templatetags.generic_template_filters import getattribute class EmployeeFilter(HorillaFilterSet): """ Filter set class for Candidate model Args: FilterSet (class): custom filter set class to apply styling """ search = django_filters.CharFilter(method="filter_by_name") search_field = django_filters.CharFilter(method="search_in") selected_search_field = django_filters.ChoiceFilter( label="Search Field", choices=[ ("employee", _("Search in : Employee")), ("reporting_manager", _("Search in : Reporting manager")), ("department", _("Search in : Department")), ("job_position", _("Search in : Job Position")), ], method="filter_by_name_and_field", widget=forms.Select( attrs={ "size": 4, "class": "oh-input__icon", "style": "border: none; overflow: hidden; display: flex; position: absolute; z-index: 999; margin-left:8%;", "onclick": "$('.filterButton')[0].click();", } ), ) employee_first_name = django_filters.CharFilter(lookup_expr="icontains") employee_last_name = django_filters.CharFilter(lookup_expr="icontains") country = django_filters.CharFilter(lookup_expr="icontains") department = django_filters.CharFilter( field_name="employee_work_info__department_id__department", lookup_expr="icontains", ) is_active = django_filters.ChoiceFilter( field_name="is_active", label="Is Active", choices=[ (True, _("Yes")), (False, _("No")), ], ) is_from_onboarding = django_filters.ChoiceFilter( field_name="is_from_onboarding", label="Is From Onboarding", choices=[ (True, _("Yes")), (False, _("No")), ], ) is_directly_converted = django_filters.ChoiceFilter( field_name="is_directly_converted", label="Is Directly Converted", choices=[ (True, _("Yes")), (False, _("No")), ], ) probation_from = django_filters.DateFilter( field_name="candidate_get__probation_end", lookup_expr="gte", widget=forms.DateInput(attrs={"type": "date"}), ) probation_till = django_filters.DateFilter( field_name="candidate_get__probation_end", lookup_expr="lte", widget=forms.DateInput(attrs={"type": "date"}), ) not_in_yet = django_filters.DateFilter( method="not_in_yet_func", widget=forms.DateInput(attrs={"type": "date"}), ) not_out_yet = django_filters.DateFilter( method="not_out_yet_func", widget=forms.DateInput(attrs={"type": "date"}), ) class Meta: """ Meta class to add the additional info """ model = Employee fields = [ "employee_first_name", "employee_last_name", "email", "badge_id", "phone", "country", "gender", "is_active", "employee_work_info__job_position_id", "employee_work_info__department_id", "department", "employee_work_info__work_type_id", "employee_work_info__employee_type_id", "employee_work_info__job_role_id", "employee_work_info__reporting_manager_id", "employee_work_info__company_id", "employee_work_info__shift_id", "employee_work_info__tags", "employee_user_id__groups", "employee_user_id__user_permissions", ] def not_in_yet_func(self, queryset, _, value): """ The method to filter out the not check-in yet employees """ # Getting the queryset for those employees dont have any attendance for the date # in value. queryset1 = queryset.exclude( employee_attendances__attendance_date=value, ) queryset2 = queryset.filter( employee_attendances__attendance_date=value, employee_attendances__attendance_clock_out__isnull=False, ) queryset = (queryset1 | queryset2).distinct() return queryset def not_out_yet_func(self, queryset, _, value): """ The method to filter out the not check-in yet employees """ # Getting the queryset for those employees dont have any attendance for the date # in value. queryset = queryset.filter( employee_attendances__attendance_date=value, employee_attendances__attendance_clock_out__isnull=True, ) return queryset def filter_queryset(self, queryset): """ Override the default filtering behavior to handle None option and filter queryset for reporting manager. """ from django.db.models import Q # Handle default accessibility and filter based on reporting manager request = getattr(_thread_locals, "request", None) if request: employee = getattr(request.user, "employee_get", None) cache_key = request.session.session_key + "accessibility_filter" accessible = check_is_accessible("employee_view", cache_key, employee) if not accessible and employee.reporting_manager.exists(): queryset = filtersubordinatesemployeemodel( request=request, queryset=queryset, perm="employee.view_employee" ) # Handle 'not_set' values in the cleaned data data = self.form.cleaned_data not_set_dict = {} for key, value in data.items(): if isinstance(value, (list, django.db.models.query.QuerySet)): if value and "not_set" in value: not_set_dict[key] = value if not_set_dict: q_objects = Q() for key, values in not_set_dict.items(): for value in values: if value == "not_set": q_objects |= Q(**{f"{key}__isnull": True}) else: q_objects |= Q(**{key: value}) return queryset.filter(q_objects) return super().filter_queryset(queryset) def filter_by_name(self, queryset, name, value): """ Employee search method """ value = value.lower() if self.data.get("search_field"): return queryset def _icontains(instance): result = str(getattribute(instance, "get_full_name")).lower() return instance.pk if value in result else None ids = list(filter(None, map(_icontains, queryset))) return queryset.filter(id__in=ids) class EmployeeReGroup: """ Class to keep the field name for group by option """ fields = [ ("", "select"), ("employee_work_info__job_position_id", "Job Position"), ("employee_work_info__department_id", "Department"), ("employee_work_info__shift_id", "Shift"), ("employee_work_info__work_type_id", "Work Type"), ("employee_work_info__job_role_id", "Job Role"), ("employee_work_info__reporting_manager_id", "Reporting Manager"), ("employee_work_info__company_id", "Company"), ] class PolicyFilter(FilterSet): """ PolicyFilter filterset class """ search = django_filters.CharFilter(field_name="title", lookup_expr="icontains") class Meta: model = Policy fields = "__all__" class DocumentRequestFilter(FilterSet): """ Custom filter for Document Requests. """ search = CharFilter(field_name="title", lookup_expr="icontains") class Meta: """ A nested class that specifies the model and fields for the filter. """ model = Document fields = [ "employee_id", "document_request_id", "status", "employee_id__employee_first_name", "employee_id__employee_last_name", "employee_id__is_active", "employee_id__gender", "employee_id__employee_work_info__job_position_id", "employee_id__employee_work_info__department_id", "employee_id__employee_work_info__work_type_id", "employee_id__employee_work_info__employee_type_id", "employee_id__employee_work_info__job_role_id", "employee_id__employee_work_info__reporting_manager_id", "employee_id__employee_work_info__company_id", "employee_id__employee_work_info__shift_id", ] class DisciplinaryActionFilter(FilterSet): """ Custom filter for Disciplinary Action. """ search = CharFilter(method=filter_by_name) start_date = django_filters.DateFilter( widget=forms.DateInput(attrs={"type": "date"}), ) class Meta: model = DisciplinaryAction ordering = ["-id"] fields = [ "employee_id", "action", "employee_id__employee_work_info__job_position_id", "employee_id__employee_work_info__department_id", "employee_id__employee_work_info__work_type_id", "employee_id__employee_work_info__job_role_id", "employee_id__employee_work_info__reporting_manager_id", "employee_id__employee_work_info__company_id", "employee_id__employee_work_info__shift_id", ]