diff --git a/onboarding/filters.py b/onboarding/filters.py index 03d747793..422b29b1a 100644 --- a/onboarding/filters.py +++ b/onboarding/filters.py @@ -2,9 +2,10 @@ filters.py Used to register filter for onboarding models """ + from django import forms -from django_filters import filters -from onboarding.models import Candidate +from django_filters import filters +from onboarding.models import Candidate, CandidateStage, OnboardingStage from base.filters import FilterSet @@ -22,3 +23,39 @@ class CandidateFilter(FilterSet): model = Candidate fields = {} + + +class OnboardingStageFilter(FilterSet): + """ + OnboardingStageFilter + """ + + search_onboarding = filters.CharFilter(field_name="stage_title", method="pipeline_search") + + class Meta: + model = OnboardingStage + fields = "__all__" + + def pipeline_search(self, queryset, _, value): + """ + This method is used to search recruitment + """ + queryset = ( + queryset.filter(stage_title__icontains=value) + | queryset.filter(candidate__candidate_id__name__icontains=value) + ) + return queryset.distinct() + + +class OnboardingCandidateFilter(FilterSet): + """ + OnboardingStageFilter + """ + + search_onboarding = filters.CharFilter( + field_name="candidate_id__name", lookup_expr="icontains" + ) + + class Meta: + model = CandidateStage + fields = "__all__" diff --git a/onboarding/templates/onboarding/filters.html b/onboarding/templates/onboarding/filters.html new file mode 100644 index 000000000..f511107d5 --- /dev/null +++ b/onboarding/templates/onboarding/filters.html @@ -0,0 +1,59 @@ +{% load i18n %} +{% load static %} +
+
+
+ {% trans 'Recruitment' %} +
+
+
+
+
+ + {{ rec_filter_obj.form.recruitment_managers }} +
+
+ + {{ rec_filter_obj.form.start_date }} +
+
+ +
+
+ + {{ rec_filter_obj.form.company_id }} +
+
+ + {{ rec_filter_obj.form.end_date }} +
+
+
+
+
+ +
+
+ {% trans 'Advanced' %} +
+
+
+
+
+ + {{ rec_filter_obj.form.start_from }} +
+
+
+
+ + {{ rec_filter_obj.form.end_till }} +
+
+
+
+
+
+ diff --git a/onboarding/templates/onboarding/kanban/kanban.html b/onboarding/templates/onboarding/kanban/kanban.html index f616d1ad5..d80b46ef2 100644 --- a/onboarding/templates/onboarding/kanban/kanban.html +++ b/onboarding/templates/onboarding/kanban/kanban.html @@ -17,137 +17,33 @@
-
-
-
{% trans "Onboarding" %}
-
- -
- -
- - -
- -
- -
- -
    -
  • - -
  • -
  • - -
  • -
-
- -
- - -
-
- -
-
+ {% include "onboarding/onboarding_view_nav.html" %} +
- + {% include "onboarding/tabs.html" %}
{% for rec in recruitments %}
- {% for stage in rec.onboarding_stage.all %} -
-
+ {% for stage in rec.stages %} + +
+
- {{stage.candidate.count}} + {{stage.grouper.candidate.count}}
-
- {% for candidate in stage.candidate.all %} +
+ {% for candidate in stage.list %}
@@ -234,6 +130,45 @@
{% endfor %} + {% if stage.list.number %} +
+ +
+ {% endif %}
diff --git a/onboarding/templates/onboarding/onboarding_table.html b/onboarding/templates/onboarding/onboarding_table.html index 89121cb05..5b632bcb4 100644 --- a/onboarding/templates/onboarding/onboarding_table.html +++ b/onboarding/templates/onboarding/onboarding_table.html @@ -1,371 +1,406 @@ {% load onboardingfilters %} {% load i18n %} {% load static %} - - -{% for stage in recruitment.onboarding_stage.all %} - +{% for stage in recruitment.stages %}
-
-
-
+ {% comment %} fixed {% endcomment %} +
+
+ {{stage.list|length}} + {{stage.grouper}} +
+ {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage or perms.onboarding.delete_onboardingstage %} +
+ {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage %} + + + + {% else %} + + + + {% endif %} + {% if request.user|stage_manages:stage or perms.onboarding.delete_onboardingstage %} +
- {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage or perms.onboarding.delete_onboardingstage %} -
- {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage %} - - {% else %} - - {% endif %} - {% if request.user|stage_manages:stage or perms.onboarding.delete_onboardingstage %} - - - - {% else %} - - {% endif %} -
- {% comment %}
-
- -
-
    - {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage %} -
  • - {% trans "Edit" %} -
  • - {% endif %} {% endcomment %} - {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage %} - {% comment %}
  • - {% trans "Bulk Change Stage" %} {% endcomment %} - - {% comment %}
  • {% endcomment %} - {% endif %} - {% comment %} {% if request.user|stage_manages:stage or perms.onboarding.delete_onboardingstage %} -
  • - {% trans "Delete" %} - -
  • - {% endif %} -
-
-
-
{% endcomment %} + + + {% else %} + + {% endif %} + {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage %} + {% endif %}
-
-
-
-
-
-
-
- -
-
-
{% trans "Candidate" %}
-
{% trans "Email" %}
-
{% trans "Job Position" %}
-
{% trans "Mobile" %}
-
{% trans "Joining Date" %}
-
{% trans "Portal Status" %}
-
{% trans "Task Status" %}
-
{% trans "Stage" %}
-
{% trans "Options" %}
- {% for task in stage.onboarding_task.all %} -
-
- {{task|truncatechars:20}} - {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingtask or perms.onboarding.delete_onboardingtask %} -
- -
-
    - {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingtask %} -
  • - {% trans "Edit" %} - -
  • - {% endif %} - {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage %} -
  • - {% trans "Bulk Change Task" %} - -
  • - {% endif %} - {% if request.user|stage_manages:stage or perms.onboarding.delete_onboardingtask %} -
  • - {% trans "Delete" %} -
  • - {% endif %} -
-
-
- {% endif %} -
-
- {% endfor %} - {% if request.user|stage_manages:stage or perms.onboarding.add_onboardingtask %} -
- -
- {% endif %} -
-
-
- {% for candidate in stage.candidate.all %} - {% if candidate.candidate_id.recruitment_id == recruitment %} -
-
-
-
- -
-
-
-
-
-
- -
- {{candidate.candidate_id}} -
-
-
{{candidate.candidate_id.email}}
-
{{candidate.candidate_id.job_position_id}}
-
{{candidate.candidate_id.mobile}}
-
{{candidate.candidate_id.joining_date}}
-
-
- {% if candidate.candidate_id.onboarding_portal.count %} - {{candidate.candidate_id.onboarding_portal.count}} / 4 - {% else %} - 0 / 4 - {% endif %} -
-
-
-
- {{candidate.task_completion_ratio}} -
-
-
- {% if request.user|stage_manages:stage or perms.onboarding.change_candidatestage %} - - {% else %} - {% for stage in recruitment.onboarding_stage.all %} - {% if candidate.onboarding_stage_id == stage %} - {{stage}} - {% endif %} - {% endfor %} - {% endif %} -
-
- -
- {% for task in stage.onboarding_task.all %} -
- {% if request.user|task_manager:task or perms.onboarding.change_candidatetask %} - {% include 'onboarding/candidate_task.html' %} - {% else %} - {% for choice in choices %} - {% if choice.0 == task.status %} - {{choice.1}} - {% endif %} - {% endfor %} - {% endif %} -
- {% endfor %} -
- {% endif %} - {% endfor %} -
-
-
-
+ {% endif %}
-

+ {% comment %} fixed {% endcomment %} + +
+ {% comment %} fixed {% endcomment %} +
+
+
+
+
+
+ +
+
+
{% trans "Candidate" %}
+
{% trans "Email" %}
+
{% trans "Job Position" %}
+
{% trans "Mobile" %}
+
{% trans "Joining Date" %}
+
{% trans "Portal Status" %}
+
{% trans "Task Status" %}
+
{% trans "Stage" %}
+
{% trans "Options" %}
+ {% for task in stage.grouper.onboarding_task.all %} +
+
+ {{task|truncatechars:20}} + {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingtask or perms.onboarding.delete_onboardingtask %} +
+ +
+
    + {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingtask %} +
  • + {% trans "Edit" %} + +
  • + {% endif %} + {% if request.user|stage_manages:stage or perms.onboarding.change_onboardingstage %} +
  • + {% trans "Bulk Change Task" %} + +
  • + {% endif %} + {% if request.user|stage_manages:stage or perms.onboarding.delete_onboardingtask %} +
  • + {% trans "Delete" %} +
  • + {% endif %} +
+
+
+ {% endif %} +
+
+ {% endfor %} + {% if request.user|stage_manages:stage or perms.onboarding.add_onboardingtask %} +
+ +
+ {% endif %} +
+
+
+ {% for candidate in stage.list %} + {% if candidate.candidate_id.recruitment_id == recruitment %} +
+
+
+
+ +
+
+
+
+
+
+ +
+ {{candidate.candidate_id}} +
+
+
{{candidate.candidate_id.email}}
+
{{candidate.candidate_id.job_position_id}}
+
{{candidate.candidate_id.mobile}}
+
{{candidate.candidate_id.joining_date}}
+
+
+ {% if candidate.candidate_id.onboarding_portal.count %} + {{candidate.candidate_id.onboarding_portal.count}} / 4 + {% else %} + 0 / 4 + {% endif %} +
+
+
+
+ {{candidate.task_completion_ratio}} +
+
+
+ {% if request.user|stage_manages:stage or perms.onboarding.change_candidatestage %} + + {% else %} + {% for stage in recruitment.onboarding_stage.all %} + {% if candidate.onboarding_stage_id == stage %} + {{stage}} + {% endif %} + {% endfor %} + {% endif %} +
+
+ +
+ {% for task in stage.grouper.onboarding_task.all %} +
+ {% if request.user|task_manager:task or perms.onboarding.change_candidatetask %} + {% include 'onboarding/candidate_task.html' %} + {% else %} + {% for choice in choices %} + {% if choice.0 == task.status %} + {{choice.1}} + {% endif %} + {% endfor %} + {% endif %} +
+ {% endfor %} +
+ {% endif %} + {% endfor %} +
+
+
+ {% comment %}till heree{% endcomment %} + +
+ {% if stage.list.paginator.num_pages %} + + {% trans "Page" %} {{ stage.list.number }} {% trans "of" %} {{ stage.list.paginator.num_pages }}. + + + {% endif %} +
+ +
+
+
{% endfor %} - - + success: function (response) { + for (let i of ids) { + var tasks = $(`[data-onboarding-task-id=${Task}][data-candidate-id=${i}]`); + tasks.val(NewStatus); + } + var alertContainer = $('
'); + var message = "{% trans 'Candidates stage updated successfully...' %}" + var alertDiv = $('
').text(`${ids.length} ${message}`); + alertContainer.append(alertDiv); + $(".messages").html(alertContainer); + }, + error: () => { + console.log("error") + } + + }) + } + $(document).ready(function() { + + + $("select[name='stage']").on("htmx:afterRequest", function(event, xhr, data) { + var alertContainer = $('
'); + var alertDiv = $('
').text("{% trans 'Candidate task stage updated successfully..' %}") + + alertContainer.append(alertDiv); + $(".messages").html(alertContainer); + }); + }); + \ No newline at end of file diff --git a/onboarding/templates/onboarding/onboarding_view.html b/onboarding/templates/onboarding/onboarding_view.html index cc5a11ad0..2f24cdfdd 100644 --- a/onboarding/templates/onboarding/onboarding_view.html +++ b/onboarding/templates/onboarding/onboarding_view.html @@ -43,126 +43,16 @@
-
-
-

{% trans "Onboarding" %}

- - - -
-
- {% if recruitments %} -
- - -
- {% endif %} - -
- -
- - {% if recruitments %} -
    -
  • - -
  • -
  • - -
  • -
-
- -
- - -
-
- {% endif %} - -
-
+{% include "onboarding/onboarding_view_nav.html" %}
{% if recruitments %} -
-
    - {% for recruitment in recruitments %} - {% if request.user|task_manages:recruitment or perms.onboarding.view_candidatestage %} -
  • - {{recruitment}} - {{recruitment.onboarding_stage.all|length}} -
  • - {% endif %} - {% endfor %} -
+ {% include "onboarding/tabs.html" %}
{% for recruitment in recruitments %} - {% if request.user|task_manages:recruitment or perms.onboarding.view_candidatestage %} - + {% if request.user|task_manages:recruitment or perms.onboarding.view_candidatestage %}
- -
{% if request.user|task_manages:recruitment or perms.onboarding.add_onboardingstage %}
@@ -174,11 +64,10 @@
{% endif %} -
+
{% include 'onboarding/onboarding_table.html' %}
-
{% endif %} {% endfor %} diff --git a/onboarding/templates/onboarding/onboarding_view_nav.html b/onboarding/templates/onboarding/onboarding_view_nav.html new file mode 100644 index 000000000..1cb33f9e5 --- /dev/null +++ b/onboarding/templates/onboarding/onboarding_view_nav.html @@ -0,0 +1,50 @@ +{% load i18n %} +
+
+

{% trans "Onboarding" %}

+ + + +
+
+
+ + +
+
    +
  • + +
  • +
  • + +
  • +
+
+ +
+ +
+ {% include "onboarding/filters.html" %} +
+
+
+
+
+{% include "filter_tags.html" %} +
+ + + {% trans "Closed" %} + + + + {% trans "Open" %} + +
\ No newline at end of file diff --git a/onboarding/templates/onboarding/tabs.html b/onboarding/templates/onboarding/tabs.html new file mode 100644 index 000000000..0930d1d64 --- /dev/null +++ b/onboarding/templates/onboarding/tabs.html @@ -0,0 +1,18 @@ +{% load i18n %} +{% load recruitmentfilters %} +{% load onboardingfilters %} + +
    + {% for rec in recruitments %} + + {% if request.user|task_manages:rec or perms.onboarding.view_candidatestage %} +
  • + {{rec.title}} + + {{rec.stages|length}} + +
  • + {% endif %} + {% endfor %} +
\ No newline at end of file diff --git a/onboarding/views.py b/onboarding/views.py index f7fedccdc..81caecf9e 100644 --- a/onboarding/views.py +++ b/onboarding/views.py @@ -32,6 +32,7 @@ from horilla import settings from horilla.decorators import login_required, hx_request_required from horilla.decorators import permission_required from base.methods import generate_pdf, get_key_instances, get_pagination, sortby +from onboarding.filters import OnboardingCandidateFilter, OnboardingStageFilter from recruitment.forms import RejectedCandidateForm from recruitment.models import Candidate, Recruitment, RecruitmentMailTemplate, RejectedCandidate from recruitment.filters import CandidateFilter, RecruitmentFilter @@ -58,6 +59,7 @@ from onboarding.decorators import ( stage_manager_can_enter, recruitment_manager_can_enter, ) +from recruitment.pipeline_grouper import group_by_queryset @login_required @@ -677,6 +679,47 @@ def email_send(request): return HttpResponse("") +def onboarding_query_grouper(request,queryset): + """ + This method is used to make group of the onboarding records + """ + groups = [] + for rec in queryset: + stages = OnboardingStageFilter(request.GET, queryset=rec.onboarding_stage.all()).qs + all_stages_grouper = [] + for stage_in_all in stages.order_by("sequence"): + all_stages_grouper.append({"grouper": stage_in_all, "list": []}) + data = {"recruitment": rec, "stages": []} + for stage in stages.order_by("sequence"): + stage_candidates = OnboardingCandidateFilter( + request.GET, + stage.candidate.order_by("sequence").filter( + candidate_id__is_active=True, + ), + ).qs + + page_name = "page" + stage.stage_title + str(rec.id) + grouper = group_by_queryset( + stage_candidates, + "onboarding_stage_id", + request.GET.get(page_name), + page_name, + ).object_list + data["stages"] = data["stages"] + grouper + existing_grouper_ids = {item["grouper"].id for item in data["stages"]} + for item in all_stages_grouper: + if item["grouper"].id not in existing_grouper_ids: + data["stages"].append( + { + "grouper": item["grouper"], + "list": [], + "dynamic_name": f'dynamic_page_page{item["grouper"].id}', + } + ) + + groups.append(data) + return groups + @login_required @all_manager_can_enter("onboarding.view_candidatestage") @@ -690,59 +733,39 @@ def onboarding_view(request): Returns: GET : return onboarding view template """ - candidates = Candidate.objects.filter(hired=True, start_onboard=True) - job_positions = JobPosition.objects.all() - # for candidate in candidates: - # recruitment =candidate.recruitment_id - # if not CandidateStage.objects.filter(candidate_id=candidate).exists(): - # try: - # onboarding_stage = OnboardingStage.objects.filter( - # recruitment_id=candidate.recruitment_id - # ).order_by("sequence")[0] - # CandidateStage( - # candidate_id=candidate, onboarding_stage_id=onboarding_stage - # ).save() - # except Exception: - # messages.error( - # request, - # _("%(recruitment)s has no stage..") - # % {"recruitment": candidate.recruitment_id}, - # ) - # if tasks := OnboardingTask.objects.filter( - # recruitment_id=candidate.recruitment_id - # ): - # for task in tasks: - # if not CandidateTask.objects.filter( - # candidate_id=candidate, onboarding_task_id=task - # ).exists(): - # CandidateTask( - # candidate_id=candidate, onboarding_task_id=task - # ).save() - - recruitments = Recruitment.objects.filter(closed=False) - status = "closed" - if request.GET.get("closed") == "closed": - recruitments = Recruitment.objects.filter(closed=True) - status = "closed" - else: - status = "" + filter_obj = RecruitmentFilter(request.GET) + # is active filteration not providing on pipeline + recruitments = filter_obj.qs.filter(is_active=True) + + status = request.GET.get("closed") + if not status: + recruitments = recruitments.filter(closed=False) onboarding_stages = OnboardingStage.objects.all() choices = CandidateTask.choice previous_data = request.GET.urlencode() - filter_obj = RecruitmentFilter(request.GET, queryset=recruitments) - paginator = Paginator(filter_obj.qs, 4) + paginator = Paginator(recruitments, 4) page_number = request.GET.get("page") page_obj = paginator.get_page(page_number) - + groups = onboarding_query_grouper(request,page_obj) + for item in groups: + setattr(item["recruitment"], "stages", item["stages"]) + filter_dict = parse_qs(request.GET.urlencode()) + if not request.GET.get("closed"): + filter_obj.form.initial["closed"] = False + filter_dict["closed"] = ["false"] + for key, val in filter_dict.copy().items(): + if val[0] == "unknown" or key == "view": + del filter_dict[key] return render( request, "onboarding/onboarding_view.html", { "recruitments": page_obj, + "rec_filter_obj": filter_obj, "onboarding_stages": onboarding_stages, "choices": choices, - "job_positions": job_positions, + "filter_dict": filter_dict, "status": status, "pd": previous_data, }, @@ -752,42 +775,13 @@ def onboarding_view(request): @login_required @all_manager_can_enter("onboarding.view_candidatestage") def kanban_view(request): - candidates = Candidate.objects.filter(hired=True, start_onboard=True) - job_positions = JobPosition.objects.all() - # for candidate in candidates: - # if not CandidateStage.objects.filter(candidate_id=candidate).exists(): - # try: - # onboarding_stage = OnboardingStage.objects.filter( - # recruitment_id=candidate.recruitment_id - # ).order_by("sequence")[0] - # CandidateStage( - # candidate_id=candidate, onboarding_stage_id=onboarding_stage - # ).save() - # except Exception: - # messages.error( - # request, - # _("%(recruitment)s has no stage..") - # % {"recruitment": candidate.recruitment_id}, - # ) - # if tasks := OnboardingTask.objects.filter( - # recruitment_id=candidate.recruitment_id - # ): - # for task in tasks: - # if not CandidateTask.objects.filter( - # candidate_id=candidate, onboarding_task_id=task - # ).exists(): - # pass - # CandidateTask( - # candidate_id=candidate, onboarding_task_id=task - # ).save() - - recruitments = Recruitment.objects.filter(closed=False) - status = "closed" - if request.GET.get("closed") == "closed": - recruitments = Recruitment.objects.filter(closed=True) - status = "closed" - else: - status = "" + filter_obj = RecruitmentFilter(request.GET) + # is active filteration not providing on pipeline + recruitments = filter_obj.qs.filter(is_active=True) + + status = request.GET.get("closed") + if not status: + recruitments = recruitments.filter(closed=False) onboarding_stages = OnboardingStage.objects.all() choices = CandidateTask.choice stage_form = OnboardingViewStageForm() @@ -795,22 +789,37 @@ def kanban_view(request): previous_data = request.GET.urlencode() filter_obj = RecruitmentFilter(request.GET, queryset=recruitments) - paginator = Paginator(filter_obj.qs, 4) + paginator = Paginator(recruitments, 4) page_number = request.GET.get("page") page_obj = paginator.get_page(page_number) + groups = onboarding_query_grouper(request,page_obj) + + for item in groups: + setattr(item["recruitment"], "stages", item["stages"]) + filter_dict = parse_qs(request.GET.urlencode()) + if not request.GET.get("closed"): + filter_obj.form.initial["closed"] = False + filter_dict["closed"] = ["false"] + for key, val in filter_dict.copy().items(): + if val[0] == "unknown" or key == "view": + del filter_dict[key] + return render( request, "onboarding/kanban/kanban.html", { "recruitments": page_obj, + "rec_filter_obj": filter_obj, "onboarding_stages": onboarding_stages, "choices": choices, - "job_positions": job_positions, + "filter_dict": filter_dict, "stage_form": stage_form, "status": status, "choices": choices, "pd": previous_data, + "card": True, + }, ) @@ -1195,7 +1204,10 @@ def candidate_stage_update(request, candidate_id, recruitment_id): POST : return candidate task template """ stage_id = request.POST.get("stage") - recruitment = Recruitment.objects.get(id=recruitment_id) + recruitments = Recruitment.objects.filter(id=recruitment_id) + groups = onboarding_query_grouper(request,recruitments) + for item in groups: + setattr(item["recruitment"], "stages", item["stages"]) stage = OnboardingStage.objects.get(id=stage_id) candidate = Candidate.objects.get(id=candidate_id) candidate_stage = CandidateStage.objects.get(candidate_id=candidate) @@ -1224,7 +1236,7 @@ def candidate_stage_update(request, candidate_id, recruitment_id): request, "onboarding/onboarding_table.html", { - "recruitment": recruitment, + "recruitment": groups[0]["recruitment"], "onboarding_stages": onboarding_stages, "choices": choices, }, diff --git a/recruitment/filters.py b/recruitment/filters.py index 2ba721a85..4089579c4 100644 --- a/recruitment/filters.py +++ b/recruitment/filters.py @@ -15,6 +15,7 @@ from recruitment.models import ( SkillZoneCandidate, Stage, RecruitmentSurvey, + SurveyTemplate, ) from base.filters import FilterSet @@ -31,7 +32,9 @@ class CandidateFilter(FilterSet): name = django_filters.CharFilter(field_name="name", lookup_expr="icontains") # for pipeline use - candidate_name = django_filters.CharFilter(field_name="name", lookup_expr="icontains") + candidate_name = django_filters.CharFilter( + field_name="name", lookup_expr="icontains" + ) start_date = django_filters.DateFilter( field_name="recruitment_id__start_date", widget=forms.DateInput(attrs={"type": "date"}), @@ -151,6 +154,12 @@ class RecruitmentFilter(FilterSet): FilterSet (class): custom filter set class to apply styling """ + candidate_name = django_filters.CharFilter( + field_name="title", method="pipeline_search" + ) + search_onboarding = django_filters.CharFilter( + field_name="title", method="onboarding_search" + ) description = django_filters.CharFilter(lookup_expr="icontains") start_date = django_filters.DateFilter( field_name="start_date", widget=forms.DateInput(attrs={"type": "date"}) @@ -226,6 +235,30 @@ class RecruitmentFilter(FilterSet): queryset = queryset | job_queryset return queryset.distinct() + def pipeline_search(self, queryset, _, value): + """ + This method is used to search recruitment + """ + queryset = ( + queryset.filter(title__icontains=value) + | queryset.filter(stage_set__stage__icontains=value) + | queryset.filter(candidate__name__icontains=value) + ) + return queryset.distinct() + + def onboarding_search(self, queryset, _, value): + """ + This method is used to search recruitment + """ + queryset = ( + queryset.filter(title__icontains=value) + | queryset.filter(onboarding_stage__stage_title__icontains=value) + | queryset.filter( + candidate__onboarding_stage__candidate_id__name__icontains=value + ) + ) + return queryset.distinct() + class StageFilter(FilterSet): """ @@ -236,6 +269,7 @@ class StageFilter(FilterSet): """ search = django_filters.CharFilter(method="filter_by_name") + candidate_name = django_filters.CharFilter(method="pipeline_search") class Meta: """ @@ -261,7 +295,7 @@ class StageFilter(FilterSet): parts = value.split() first_name = parts[0] last_name = " ".join(parts[1:]) if len(parts) > 1 else "" - + recruitment_query = queryset.filter(recruitment_id__title__icontains=value) # Filter the queryset by first name and last name stage_queryset = queryset.filter(stage__icontains=value) if first_name and last_name: @@ -278,7 +312,17 @@ class StageFilter(FilterSet): stage_managers__employee_last_name__icontains=last_name ) - return queryset | stage_queryset + queryset = queryset | stage_queryset | recruitment_query + return queryset + + def pipeline_search(self, queryset, _, value): + """ + This method is used to search recruitment + """ + queryset = queryset.filter(stage__icontains=value) | queryset.filter( + candidate__name__icontains=value + ) + return queryset.distinct() class SurveyFilter(FilterSet): @@ -310,6 +354,20 @@ class SurveyFilter(FilterSet): ] +class SurveyTemplateFilter(django_filters.FilterSet): + """ + SurveyTemplateFilter + """ + question = django_filters.CharFilter( + lookup_expr="icontains", + label="Title", + field_name="title", + ) + class Meta: + model = SurveyTemplate + fields = "__all__" + + class CandidateReGroup: """ Class to keep the field name for group by option @@ -342,7 +400,6 @@ class SkillZoneFilter(FilterSet): "skillzonecandidate_set__candidate_id__recruitment_id", "skillzonecandidate_set__candidate_id__job_position_id", "skillzonecandidate_set__candidate_id__stage_id__stage_type", - ]