[ADD] RECRUITMENT: Group By filter to candidate view

This commit is contained in:
Horilla
2023-11-06 12:23:17 +05:30
parent d171d8f3f1
commit 80b50ca034
5 changed files with 225 additions and 8 deletions

View File

@@ -282,3 +282,14 @@ class SurveyFilter(FilterSet):
exclude = [
"sequence",
]
class CandidateReGroup:
"""
Class to keep the field name for group by option
"""
fields = [
("","select"),
("recruitment_id","Recruitment"),
("job_position_id","Job Position"),
("hired", "Status"),
]

View File

@@ -109,9 +109,6 @@
<label class="oh-label">{% trans "End Date" %}</label>
{{f.form.end_date}}
</div>
</div>
</div>
</div>
@@ -139,6 +136,34 @@
</div>
</div>
</div>
<div class="oh-accordion">
<div class="oh-accordion-header">{% trans "Group By" %}</div>
<div class="oh-accordion-body">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
<div class="oh-input-group">
<label class="oh-label">{% trans "Field" %}</label>
</div>
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
<div class="oh-input-group">
<select
class="oh-select mt-1"
id="id_field"
name="field"
class="select2-selection select2-selection--single"
id="gp"
>
{% for field in gp_fields %}
<option value="{{ field.0 }}">{% trans field.1 %}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="oh-dropdown__filter-footer">

View File

@@ -0,0 +1,170 @@
{% load attendancefilters %} {% load basefilters %} {% load static %}
{% load i18n %} {% include 'filter_tags.html' %}
<div class="oh-card">
{% dynamic_regroup data by field as candidate_grouper %}
{% for candidate_list in candidate_grouper %}
<div class="oh-accordion-meta">
<div class="oh-accordion-meta__item">
<div class="oh-accordion-meta__header">
<span class="oh-accordion-meta__title pt-3 pb-3">
<div class="oh-tabs__input-badge-container">
<span
class="oh-badge oh-badge--secondary oh-badge--small oh-badge--round mr-1"
>
{{candidate_list.list|length}}
</span>
{{candidate_list.grouper}}
</div>
</span>
</div>
<div class="oh-accordion-meta__body d-none">
<div class="oh-sticky-table oh-sticky-table--no-overflow mb-5">
<div class="oh-sticky-table">
<div class="oh-sticky-table__table oh-table--sortable">
<div class="oh-sticky-table__thead">
<div class="oh-sticky-table__tr">
<div class="oh-sticky-table__th" style="width:10px;">
<input type="checkbox" class="oh-input oh-input__checkbox mt-1 mr-2 all-candidate" title="Select All"
id = "allCandidate"/>
</div>
<div class="oh-sticky-table__th" hx-target='#section' hx-get="{% url 'search-candidate' %}?{{pd}}&orderby=name&view=list">{% trans "Candidates" %}</div>
<div class="oh-sticky-table__th">{% trans "Email" %}</div>
<div class="oh-sticky-table__th">{% trans "Phone" %}</div>
<div class="oh-sticky-table__th">{% trans "Recruitment" %}</div>
<div class="oh-sticky-table__th">{% trans "Job Position" %}</div>
<div class="oh-sticky-table__th">{% trans "Resume" %}</div>
{% comment %} <div class="oh-sticky-table__th"></div> {% endcomment %}
<div class="oh-sticky-table__th"></div>
</div>
</div>
{% for cand in candidate_list.list %}
<div class="oh-sticky-table__tbody ui-sortable">
<div class="oh-sticky-table__tr ui-sortable-handle">
<div class="oh-sticky-table__sd {% if cand.canceled %} row-status--red
{% elif cand.hired %} row-status--yellow
{% else %} row-status--purple
{% endif %}">
<div class="">
<input
type="checkbox"
id="{{cand.id}}"
class="oh-input candidate-checkbox oh-input__checkbox mt-2 mr-2 all-candidate-row"
/>
</div>
</div>
<div class="oh-sticky-table__td candidate {% if cand.hired %}hired-cand{% endif %}">
<div class="d-flex">
<div class="oh-profile oh-profile--md">
<div class="oh-profile__avatar mr-1">
<img src="{{cand.get_avatar}}"
class="oh-profile__image"
alt="Username" />
</div>
<span class="oh-profile__name oh-text--dark">{{cand}}</span>
</div>
</div>
</div>
<a href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td ">{{cand.email}}</a>
<a href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td">{{cand.mobile}}</a>
<a href="#" style="color: inherit;text-decoration: none;"
class="oh-sticky-table__td">{{cand.recruitment_id}}</a>
<a href="#" style="color: inherit;text-decoration: none;"
class="oh-sticky-table__td">{{cand.job_position_id}}</a>
<a style="color: inherit;text-decoration: none;" class="oh-sticky-table__td" href="/media/{{cand.resume}}"
target="_blank" rel="noopener noreferrer"><span class="oh-btn oh-btn--info"> {% trans "Resume" %}</span></a>
{% comment %} <a href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td">
{% if perms.recruitment.view_history %}
<button hx-get="{% url 'candidate-history' cand.id %}" hx-target='#section'
class="oh-btn oh-btn--info">history</button>
{% endif %}
</a> {% endcomment %}
<div href="#" style="color: inherit;text-decoration: none;" class="oh-sticky-table__td">
<div class="oh-btn-group">
{% if perms.recruitment.change_candidate %}
<a href="{% url 'rec-candidate-update' cand.id %}" hx-target='#updateFormContainer' hx-swap='innerHTML'
class="oh-btn oh-btn--light-bkg w-50" title="Edit"><ion-icon name="create-outline"></ion-icon></a>
{% endif %}
{% if perms.recruitment.delete_candidate %}
{% if cand.is_active %}
<form action="{% url 'rec-candidate-archive' cand.id %}"title="Archive" onsubmit="return confirm('{% trans "Do you want to archive this candidate" %}')" method='post'
class="w-50">
{% csrf_token %}
<button type='submit' class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100"
><ion-icon name="archive" title="Archive"></ion-icon></button>
</form>
{% else %}
<form action="{% url 'rec-candidate-archive' cand.id %}" title="Un Archive" onsubmit="return confirm('{% trans "Do you want to un-archive this candidate" %}')" method='post'
class="w-50">
{% csrf_token %}
<button type='submit' class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100"
><ion-icon name="archive"></ion-icon></button>
</form>
{% endif %}
{% endif %}
{% if perms.recruitment.delete_candidate %}
<form action="{% url 'rec-candidate-delete' cand.id %}" onsubmit="return confirm('{% trans "Do you want to delete this candidate" %}')" method='post'
onsubmit="Are you sure want to delete this candidate?" class="w-50">
{% csrf_token %}
<button type='submit' class="oh-btn oh-btn--danger-outline oh-btn--light-bkg w-100"
title="Remove"><ion-icon name="trash-outline"></ion-icon></button>
</form>
{% endif %}
</div>
</div>
</a>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
<div class="oh-pagination">
<span class="oh-pagination__page" data-toggle="modal" data-target="#addEmployeeModal">
{% trans "Page" %} {{ data.number }} {% trans "of" %} {{ data.paginator.num_pages }}.
</span>
<nav class="oh-pagination__nav">
<div class="oh-pagination__input-container me-3">
<span class="oh-pagination__label me-1">{% trans "Page" %}</span>
<input type="number" name="page" class="oh-pagination__input" value="{{data.number}}"
hx-get="{% url 'search-candidate' %}?{{pd}}&view=list" hx-target="#section" min="1" />
<span class="oh-pagination__label">{% trans "of" %} {{data.paginator.num_pages}}</span>
</div>
<ul class="oh-pagination__items">
{% if data.has_previous %}
<li class="oh-pagination__item oh-pagination__item--wide">
<a hx-target='#section' hx-get="{% url 'search-candidate' %}?{{pd}}&page=1&view=list"
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "First" %}</a>
</li>
<li class="oh-pagination__item oh-pagination__item--wide">
<a hx-target='#section'
hx-get="{% url 'search-candidate' %}?{{pd}}&page={{ data.previous_page_number }}&view=list"
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "Previous" %}</a>
</li>
{% endif %}
{% if data.has_next %}
<li class="oh-pagination__item oh-pagination__item--wide">
<a hx-target='#section' hx-get="{% url 'search-candidate' %}?{{pd}}&page={{ data.next_page_number }}&view=list"
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "Next" %}</a>
</li>
<li class="oh-pagination__item oh-pagination__item--wide">
<a hx-target='#section'
hx-get="{% url 'search-candidate' %}?{{pd}}&page={{ data.paginator.num_pages }}&view=list"
class="oh-pagination__link" onclick=tickCandidateCheckboxes()>{% trans "Last" %}</a>
</li>
{% endif %}
</ul>
</nav>
</div>

View File

@@ -86,6 +86,13 @@ def candidate_search(request):
if request.GET.get("view") == "list":
template = "candidate/candidate_list.html"
candidates = sortby(request, candidates, "orderby")
field = request.GET.get("field")
if field != "" and field is not None:
field_copy = field.replace(".", "__")
candidates = candidates.order_by(field_copy)
template = "candidate/group_by.html"
candidates = paginator_qry(candidates, request.GET.get("page"))
return render(
request,
@@ -94,6 +101,7 @@ def candidate_search(request):
"data": candidates,
"pd": previous_data,
"filter_dict": data_dict,
"field":field,
},
)
@@ -116,19 +124,21 @@ def candidate_filter_view(request):
"""
This method is used for filter,pagination and search candidate.
"""
templete = "candidate/candidate_card.html"
candidates = Candidate.objects.filter(is_active=True)
template = "candidate/candidate_card.html"
if request.GET.get('view') == 'list':
templete = "candidate/candidate_list.html"
template = "candidate/candidate_list.html"
previous_data = request.GET.urlencode()
filter_obj = CandidateFilter(
request.GET, queryset=Candidate.objects.filter(is_active=True)
request.GET, queryset=candidates
)
paginator = Paginator(filter_obj.qs, 24)
page_number = request.GET.get("page")
page_obj = paginator.get_page(page_number)
return render(
request,
templete,
template,
{"data": page_obj, "pd": previous_data},
)

View File

@@ -33,7 +33,7 @@ from horilla.decorators import permission_required, login_required, hx_request_r
from base.methods import get_key_instances
from recruitment.views.paginator_qry import paginator_qry
from recruitment.models import Recruitment, Candidate, Stage, StageNote
from recruitment.filters import CandidateFilter, RecruitmentFilter, StageFilter
from recruitment.filters import CandidateFilter, CandidateReGroup, RecruitmentFilter, StageFilter
from recruitment.methods import recruitment_manages
from recruitment.decorators import manager_can_enter, recruitment_manager_can_enter
from recruitment.forms import (
@@ -843,6 +843,7 @@ def candidate_view(request):
"export_obj": export_obj,
"view_type": view_type,
"filter_dict": data_dict,
"gp_fields" : CandidateReGroup.fields
},
)