2023-05-10 15:06:57 +05:30
from django . shortcuts import render , redirect
from . models import Recruitment , Candidate , Stage
from horilla . decorators import permission_required , login_required , hx_request_required
from django . http import JsonResponse , HttpResponse , HttpResponseRedirect
from employee . models import Employee
from recruitment . forms import RecruitmentCreationForm , CandidateCreationForm , StageCreationForm , ApplicationForm , RecruitmentDropDownForm , StageDropDownForm , CandidateDropDownForm , StageNoteForm
from django . contrib . auth . models import User , Permission , Group
from django . core import serializers
from django . contrib import messages
from django . views . decorators . http import require_http_methods
from django . core . paginator import Paginator
from recruitment . filters import CandidateFilter , RecruitmentFilter , StageFilter
from django . views . decorators . http import require_http_methods
from django . forms import formset_factory
from recruitment . filters import RecruitmentFilter
from recruitment . models import StageNote
import json
from django . core . mail import send_mail
from horilla import settings
from django . db . models import Q
from recruitment . methods import is_recruitmentmanager , is_stagemanager , recruitment_manages , stage_manages
from base . methods import sortby
from recruitment . decorators import manager_can_enter , recruitment_manager_can_enter
from notifications . signals import notify
from django . utils . translation import gettext_lazy as _
# Create your views here.
def is_stagemanager ( request , stage_id = False ) :
"""
This method is used to identify the employee is a stage manager or not , if stage_id is passed through args , method will
check the employee is manager to the corresponding stage , return tuple with boolean and all stages that employee is manager .
if called this method without stage_id args it will return boolean with all the stage that the employee is stage manager
Args :
request : django http request
stage_id : stage instance id
"""
user = request . user
employee = user . employee_get
if not stage_id :
return ( employee . stage_set . exists ( ) or user . is_superuser , employee . stage_set . all ( ) )
stage = Stage . objects . get ( id = stage_id )
return employee in stage . stage_managers . all ( ) or user . is_superuser or is_recruitmentmanager ( request , rec_id = stage . recruitment_id . id ) [ 0 ] , employee . stage_set . all ( )
def is_recruitmentmanager ( request , rec_id = False ) :
"""
This method is used to identify the employee is a recruitment manager or not , if rec_id is passed through args , method will
check the employee is manager to the corresponding recruitment , return tuple with boolean and all recruitment that employee is manager .
if called this method without recruitment args it will return boolean with all the recruitment that the employee is recruitment manager
Args :
request : django http request
rec_id : recruitment instance id
"""
user = request . user
employee = user . employee_get
if not rec_id :
return employee . recruitment_set . exists ( ) or user . is_superuser , employee . recruitment_set . all ( )
recruitment = Recruitment . objects . get ( id = rec_id )
return employee in recruitment . recruitment_managers . all ( ) or user . is_superuser , employee . recruitment_set . all ( )
def stages_create ( recruitment : object ) :
"""
This method is used to create some default stages when create recruitment
Args :
id : recruitment instance
"""
new_stage = Stage . objects . create (
recruitment_id = recruitment ,
stage = ' New ' ,
sequence = 1 ,
stage_type = ' initial '
)
interview_stage = Stage . objects . create (
recruitment_id = recruitment ,
stage = ' Interview ' ,
sequence = 2 ,
stage_type = ' interview '
)
hired_stage = Stage . objects . create (
recruitment_id = recruitment ,
stage = ' Hired ' ,
sequence = 3 ,
stage_type = ' hired '
)
return
def paginator_qry ( qryset , page_number ) :
"""
This method is used to generate common paginator limit .
"""
paginator = Paginator ( qryset , 50 )
qryset = paginator . get_page ( page_number )
return qryset
@login_required
@permission_required ( ' recruitment.add_recruitment ' )
def recruitment ( request ) :
"""
This method is used to create recruitment , when create recruitment this method
add recruitment view , create candidate , change stage sequence and so on , some of
the permission is checking manually instead of using django permission permission
to the recruitment managers
"""
form = RecruitmentCreationForm ( )
if request . method == ' POST ' :
form = RecruitmentCreationForm ( request . POST )
if form . is_valid ( ) :
recruitment = form . save ( )
messages . success ( request , _ ( ' Recruitment added. ' ) )
try :
managers = recruitment . recruitment_managers . select_related (
' employee_user_id ' )
users = [ employee . employee_user_id for employee in managers ]
2023-05-18 15:05:28 +05:30
notify . send ( request . user . employee_get , recipient = users , verb = " You are chosen as one of recruitment manager " ,
2023-05-10 15:06:57 +05:30
icon = " people-circle " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
response = render (
request , ' recruitment/recruitment_form.html ' , { ' form ' : form } )
return HttpResponse ( response . content . decode ( ' utf-8 ' ) + ' <script>location.reload();</script> ' )
return render ( request , ' recruitment/recruitment_form.html ' , { ' form ' : form } )
@login_required
@permission_required ( ' recruitment.change_recruitment ' )
@require_http_methods ( [ ' POST ' ] )
def remove_recruitment_manager ( request , mid , rid ) :
"""
This method is used to remove selected manager from the recruitment ,
when remove the manager permissions also removed if the employee is not
exists in more stage manager or recruitment manager
Args :
mid : employee manager_id in the recruitment
rid : recruitment_id
"""
recruitment = Recruitment . objects . get ( id = rid )
manager = Employee . objects . get ( id = mid )
recruitment . recruitment_managers . remove ( manager )
messages . success ( request , _ ( ' Recruitment manager removed successfully. ' ) )
notify . send ( request . user . employee_get , recipient = manager . employee_user_id ,
verb = f " You are removed from recruitment manager from { recruitment } " , icon = " person-remove " , redirect = " " )
recruitment = Recruitment . objects . all ( )
previous_data = request . environ [ ' QUERY_STRING ' ]
return render ( request , ' recruitment/recruitment_component.html ' , { ' data ' : paginator_qry ( recruitment , request . GET . get ( ' page ' ) ) , ' pd ' : previous_data } )
@login_required
@permission_required ( ' recruitment.view_recruitment ' )
def recruitment_view ( request ) :
"""
This method is used to render all recruitment to view
"""
if not request . GET :
request . GET . copy ( ) . update ( { ' is_active ' : ' on ' } )
form = RecruitmentCreationForm ( )
filter = RecruitmentFilter ( request . GET , queryset = Recruitment . objects . all ( ) )
return render ( request , ' recruitment/recruitment_view.html ' , { ' data ' : paginator_qry ( filter . qs , request . GET . get ( ' page ' ) ) , ' f ' : filter , ' form ' : form } )
@login_required
@permission_required ( ' recruitment.view_recruitment ' )
def recruitment_search ( request ) :
"""
This method is used to search recruitment
"""
filter = RecruitmentFilter ( request . GET )
previous_data = request . environ [ ' QUERY_STRING ' ]
recruitment = sortby ( request , filter . qs , ' orderby ' )
return render ( request , ' recruitment/recruitment_component.html ' , {
' data ' : paginator_qry ( recruitment , request . GET . get ( ' page ' ) ) ,
' pd ' : previous_data } )
@login_required
@permission_required ( ' recruitment.change_recruitment ' )
@hx_request_required
def recruitment_update ( request , id ) :
"""
This method is used to update the recruitment , when updating the recruitment ,
any changes in manager is exists then permissions also assigned to the manager
Args :
id : recruitment_id
"""
recruitment = Recruitment . objects . get ( id = id )
form = RecruitmentCreationForm ( instance = recruitment )
if request . method == ' POST ' :
form = RecruitmentCreationForm (
request . POST , instance = recruitment )
if form . is_valid ( ) :
recruitment = form . save ( )
messages . success ( request , _ ( ' Recruitment Updated. ' ) )
response = render (
request , ' recruitment/recruitment_form.html ' , { ' form ' : form } )
try :
managers = recruitment . recruitment_managers . select_related (
' employee_user_id ' )
users = [ employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " { recruitment } is updated, You are chosen as one of managers " , icon = " people-circle " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
return HttpResponse ( response . content . decode ( ' utf-8 ' ) + ' <script>location.reload();</script> ' )
return render ( request , ' recruitment/recruitment_update_form.html ' , { ' form ' : form } )
@login_required
@permission_required ( ' recruitment.delete_recruitment ' )
@require_http_methods ( [ ' POST ' ] )
def recruitment_delete ( request , id ) :
"""
This method is used to permanently delete the recruitment
Args :
id : recruitment_id
"""
recruitment = Recruitment . objects . get ( id = id )
recruitment_mangers = recruitment . recruitment_managers . all ( )
all_stage_permissions = Permission . objects . filter (
content_type__app_label = ' recruitment ' , content_type__model = ' stage ' )
all_candidate_permissions = Permission . objects . filter (
content_type__app_label = ' recruitment ' , content_type__model = ' candidate ' )
for manager in recruitment_mangers :
all_this_manger = manager . recruitment_set . all ( )
if len ( all_this_manger ) == 1 :
for stage_permission in all_candidate_permissions :
manager . employee_user_id . user_permissions . remove (
stage_permission . id )
for candidate_permission in all_stage_permissions :
manager . employee_user_id . user_permissions . remove (
candidate_permission . id )
try :
recruitment . delete ( )
messages . success ( request , _ ( ' Recruitment deleted successfully. ' ) )
except Exception as e :
messages . error ( request , e )
messages . error ( request , _ ( " You cannot delete this recruitment " ) )
recruitment = Recruitment . objects . all ( )
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
@login_required
@manager_can_enter ( ' recruitment.view_recruitment ' )
def recruitment_pipeline ( request ) :
"""
This method is used to filter out candidate through pipeline structure
"""
view = request . GET . get ( ' view ' )
template = ' pipeline/pipeline.html '
if view == ' card ' :
template = ' pipeline/pipeline_card.html '
recruitment_form = RecruitmentDropDownForm ( )
stage_form = StageDropDownForm ( )
candidate_form = CandidateDropDownForm ( )
recruitment = Recruitment . objects . filter ( is_active = True , closed = False )
if request . method == ' POST ' :
if request . POST . get ( ' recruitment_managers ' ) is not None and request . user . has_perm ( ' add_recruitment ' ) :
recruitment_form = RecruitmentDropDownForm ( request . POST )
if recruitment_form . is_valid ( ) :
recruitment = recruitment_form . save ( )
recruitment_form = RecruitmentDropDownForm ( )
messages . success ( request , _ ( ' Recruitment added. ' ) )
try :
managers = recruitment . recruitment_managers . select_related (
' employee_user_id ' )
users = [ employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " You are chosen as recruitment manager for the recruitment { recruitment } " , icon = " people-circle " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
elif request . FILES . get ( ' resume ' ) is not None :
if request . user . has_perm ( ' add_candidate ' ) or is_stagemanager ( request , ) :
candidate_form = CandidateDropDownForm (
request . POST , request . FILES )
if candidate_form . is_valid ( ) :
candidate = candidate_form . save ( )
candidate_form = CandidateDropDownForm ( )
try :
managers = candidate . stage_id . stage_managers . select_related (
' employee_user_id ' )
users = [
employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " New candidate arrived on stage { stage . stage } " , icon = " person-add " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
messages . success ( request , _ ( ' Candidate added. ' ) )
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
elif request . POST . get ( ' stage_managers ' ) and request . user . has_perm ( ' add_stage ' ) :
stage_form = StageDropDownForm ( request . POST )
if stage_form . is_valid ( ) :
if recruitment_manages ( request , stage_form . instance . recruitment_id ) or request . user . has_perm ( ' recruitment.add_stage ' ) :
stage = stage_form . save ( )
stage_form = StageDropDownForm ( )
messages . success ( request , _ ( ' Stage added. ' ) )
try :
managers = stage . stage_managers . select_related (
' employee_user_id ' )
users = [
employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " You are chosen as a stage manager on the stage { stage . stage } in recruitment { stage . recruitment_id } " , icon = " people-circle " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
messages . info ( request , _ ( ' You dont have access ' ) )
return render ( request , template , { ' recruitment ' : recruitment , ' recruitment_form ' : recruitment_form , ' stage_form ' : stage_form , ' candidate_form ' : candidate_form } )
@login_required
@permission_required ( ' recruitment.view_recruitment ' )
def recruitment_pipeline_card ( request ) :
"""
This method is used to render pipeline card structure .
"""
search = request . GET . get ( ' search ' )
search = search if search != None else ' '
recruitment = Recruitment . objects . all ( )
candidates = Candidate . objects . filter (
name__icontains = search , is_active = True )
stages = Stage . objects . all ( )
return render ( request , ' pipeline/pipeline_components/pipeline_card_view.html ' , { ' recruitment ' : recruitment , ' candidates ' : candidates , ' stages ' : stages } )
@login_required
@permission_required ( ' recruitment.view_candidate ' )
def pipeline_candidate_search ( request ) :
"""
This method is used to search candidate
"""
search = request . GET [ ' search ' ]
template = ' pipeline/pipeline_components/kanban_tabs.html '
if request . GET . get ( ' view ' ) == ' card ' :
template = ' pipeline/pipeline_components/kanban_tabs.html '
return render ( request , template )
@login_required
@recruitment_manager_can_enter ( ' recruitment.change_stage ' )
def stage_update_pipeline ( request , id ) :
"""
This method is used to update stage from pipeline view
"""
stage = Stage . objects . get ( id = id )
form = StageCreationForm ( instance = stage )
if request . POST :
form = StageCreationForm ( request . POST , instance = stage )
if form . is_valid ( ) :
stage = form . save ( )
messages . success ( request , _ ( ' Stage updated. ' ) )
try :
managers = stage . stage_managers . select_related (
' employee_user_id ' )
users = [ employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " { stage . stage } stage in recruitment { stage . recruitment_id } is updated, You are chosen as one of managers " , icon = " people-circle " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
return render ( request , ' pipeline/form/stage_update.html ' , { ' form ' : form } )
@login_required
@recruitment_manager_can_enter ( ' recruitment.change_recruitment ' )
def recruitment_update_pipeline ( request , id ) :
"""
This method is used to update recruitment from pipeline view
"""
recruitment = Recruitment . objects . get ( id = id )
form = RecruitmentCreationForm ( instance = recruitment )
if request . POST :
form = RecruitmentCreationForm ( request . POST , instance = recruitment )
if form . is_valid ( ) :
recruitment = form . save ( )
messages . success ( request , _ ( ' Recruitment updated. ' ) )
try :
managers = recruitment . recruitment_managers . select_related (
' employee_user_id ' )
users = [ employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " { recruitment } is updated, You are chosen as one of managers " , icon = " people-circle " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
return render ( request , ' pipeline/form/recruitment_update.html ' , { ' form ' : form } )
@login_required
@permission_required ( ' recruitment.delete_recruitment ' )
@require_http_methods ( [ ' POST ' ] )
def recruitment_delete_pipeline ( request , id ) :
recruitment = Recruitment . objects . get ( id = id )
try :
recruitment . delete ( )
messages . success ( request , _ ( ' Recruitment deleted. ' ) )
except Exception as e :
messages . error ( request , e )
messages . error ( request , _ ( ' Recruitment already in use. ' ) )
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
@login_required
@manager_can_enter ( ' recruitment.change_candidate ' )
def candidate_stage_update ( request , id ) :
"""
This method is a ajax method used to update candidate stage when drag and drop
the candidate from one stage to another on the pipeline template
Args :
id : candidate_id
"""
stage_id = request . POST [ ' stageId ' ]
candidate = Candidate . objects . get ( id = id )
candidate_history = candidate . candidate_history . all ( ) . first ( )
stage = Stage . objects . get ( id = stage_id )
previous_stage = candidate_history . stage_id
if previous_stage == stage :
return JsonResponse ( { ' type ' : ' info ' , ' message ' : _ ( ' No change detected. ' ) } )
"""
Here set the last updated schedule date on this stage if schedule exists in history
"""
candidate_history = candidate . candidate_history . filter ( stage_id = stage )
schedule_date = None
if candidate_history . exists ( ) :
# this condition is executed when a candidate dropped back to any previous
# stage, if there any scheduled date then set it back
schedule_date = candidate_history . first ( ) . schedule_date
stage_manager_on_this_recruitment = is_stagemanager (
request ) [ 1 ] . filter ( recruitment_id = stage . recruitment_id ) . exists ( )
if stage_manager_on_this_recruitment or request . user . is_superuser or is_recruitmentmanager ( rec_id = stage . recruitment_id . id ) [ 0 ] :
candidate . stage_id = stage
candidate . schedule_date = None
candidate . hired = False
candidate . schedule_date = schedule_date
candidate . start_onboard = False
if stage . stage_type == ' hired ' :
candidate . hired = True
candidate . save ( )
try :
managers = stage . stage_managers . select_related ( ' employee_user_id ' )
users = [ employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " New candidate arrived on stage { stage . stage } " , icon = " person-add " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
return JsonResponse ( { ' type ' : ' success ' , ' message ' : _ ( ' Candidate stage updated ' ) } )
@login_required
@hx_request_required
@manager_can_enter ( ' recruitment.add_stagenote ' )
def add_note ( request , id = None ) :
"""
This method renders template component to add candidate remark
"""
form = StageNoteForm ( initial = { ' candidate_id ' : id } )
if request . method == ' POST ' :
form = StageNoteForm ( request . POST , )
if form . is_valid ( ) :
note = form . save ( commit = False )
note . stage_id = note . candidate_id . stage_id
note . updated_by = request . user . employee_get
note . save ( )
messages . success ( request , _ ( ' Note added successfully.. ' ) )
response = render (
request , ' pipeline/pipeline_components/add_note.html ' , { ' form ' : form } )
return HttpResponse ( response . content . decode ( ' utf-8 ' ) + ' <script>location.reload();</script> ' )
return render ( request , ' pipeline/pipeline_components/add_note.html ' , { ' note_form ' : form , } )
@login_required
@hx_request_required
@manager_can_enter ( ' recruitment.view_stagenote ' )
def view_note ( request , id ) :
"""
This method renders a template components to view candidate remark or note
Args :
id : candidate instance id
"""
candidate = Candidate . objects . get ( id = id )
return render ( request , ' pipeline/pipeline_components/view_note.html ' , { ' cand ' : candidate } )
@login_required
@permission_required ( ' recruitment.change_stagenote ' )
def note_update ( request , id ) :
"""
This method is used to update the stage not
Args :
id : stage note instance id
"""
note = StageNote . objects . get ( id = id )
form = StageNoteForm ( instance = note )
if request . POST :
form = StageNoteForm ( request . POST , instance = note )
if form . is_valid ( ) :
form . save ( )
messages . success ( request , _ ( ' Note updated successfully... ' ) )
response = render (
request , ' pipeline/pipeline_components/update_note.html ' , { ' form ' : form } )
return HttpResponse ( response . content . decode ( ' utf-8 ' ) + ' <script>location.reload();</script> ' )
return render ( request , ' pipeline/pipeline_components/update_note.html ' , { ' form ' : form } )
@login_required
@permission_required ( ' recruitment.delete_stagenote ' )
def note_delete ( request , id ) :
"""
This method is used to delete the stage note
"""
note = StageNote . objects . get ( id = id )
candidate = note . candidate_id
try :
note . delete ( )
messages . success ( request , _ ( ' Note deleted ' ) )
except Exception as e :
messages . error ( request , e )
messages . error ( request , _ ( ' You cannot delete this note. ' ) )
return render ( request , ' pipeline/pipeline_components/view_note.html ' , { ' cand ' : candidate } )
@login_required
@require_http_methods ( [ ' DELETE ' ] )
@permission_required ( ' recruitment.delete_stagenote ' )
def candidate_remark_delete ( request , id ) :
"""
This method is used to delete the candidate stage note
Args :
id : stage note instance id
"""
stage_note = StageNote . objects . get ( id = id )
candidate = stage_note . candidate_note_id . candidate_id
try :
stage_note . delete ( )
messages . success ( request , _ ( ' Note deleted ' ) )
except Exception as e :
messages . error ( request , e )
messages . error ( request , _ ( ' You cannot delete this note. ' ) )
return render ( request , ' pipeline/pipeline_components/candidate_remark_view.html ' , { ' cand ' : candidate } )
@login_required
@permission_required ( ' recruitment.change_candidate ' )
def candidate_schedule_date_update ( request ) :
"""
This is a an ajax method to update schedule date for a candidate
"""
candidate_id = request . POST [ ' candidateId ' ]
schedule_date = request . POST [ ' date ' ]
candidate = Candidate . objects . get ( id = candidate_id )
candidate . schedule_date = schedule_date
candidate . save ( )
return JsonResponse ( { ' message ' : ' congratulations ' } )
@login_required
@permission_required ( ' recruitment.add_stage ' )
def stage ( request ) :
"""
This method is used to create stages , also several permission assigned to the stage managers
"""
form = StageCreationForm ( )
if request . method == ' POST ' :
form = StageCreationForm ( request . POST )
if form . is_valid ( ) :
stage = form . save ( )
recruitment = stage . recruitment_id
rec_stages = Stage . objects . filter (
recruitment_id = recruitment , is_active = True ) . order_by ( ' sequence ' ) . last ( )
if rec_stages . sequence is None :
stage . sequence = 1
else :
stage . sequence = rec_stages . sequence + 1
stage . save ( )
messages . success ( request , _ ( ' Stage added. ' ) )
try :
managers = stage . stage_managers . select_related (
' employee_user_id ' )
users = [ employee . employee_user_id for employee in managers ]
notify . send ( request . user . employee_get , recipient = users ,
verb = f " Stage { stage } is updated on recruitment { stage . recruitment_id } , You are chosen as one of managers " , icon = " people-circle " , redirect = " /recruitment/pipeline " )
except Exception as e :
pass
response = render ( request , ' stage/stage_form.html ' , { ' form ' : form } )
return HttpResponse ( response . content . decode ( ' utf-8 ' ) + ' <script>location.reload();</script> ' )
return render ( request , ' stage/stage_form.html ' , { ' form ' : form } )
@login_required
@permission_required ( ' recruitment.view_stage ' )
def stage_view ( request ) :
"""
This method is used to render all stages to a template
"""
stages = Stage . objects . filter ( )
filter = StageFilter ( )
form = StageCreationForm ( )
return render ( request , ' stage/stage_view.html ' , {
' data ' : paginator_qry ( stages , request . GET . get ( ' page ' ) ) , ' form ' : form ,
' f ' : filter } )
@login_required
@permission_required ( ' recruitment.view_stage ' )
def stage_search ( request ) :
"""
This method is used to search stage
"""
stages = StageFilter ( request . GET ) . qs
previous_data = request . environ [ ' QUERY_STRING ' ]
stages = sortby ( request , stages , ' orderby ' )
return render ( request , ' stage/stage_component.html ' , { ' data ' : paginator_qry ( stages , request . GET . get ( ' page ' ) ) , ' pd ' : previous_data } )
@login_required
@permission_required ( ' recruitment.change_stage ' )
def remove_stage_manager ( request , mid , sid ) :
"""
This method is used to remove selected stage manager and also removing the given
permission if the employee is not exists in more stage manager or recruitment manager
Args :
mid : manager_id in the stage
sid : stage_id
"""
stage = Stage . objects . get ( id = sid )
manager = Employee . objects . get ( id = mid )
notify . send ( request . user . employee_get , recipient = manager . employee_user_id ,
verb = f " You are removed from stage managers from stage { stage } " , icon = " person-remove " , redirect = " " )
stage . stage_managers . remove ( manager )
messages . success ( request , _ ( ' Stage manager removed successfully. ' ) )
stages = Stage . objects . all ( )
previous_data = request . environ [ ' QUERY_STRING ' ]
return render ( request , ' stage/stage_component.html ' , { ' data ' : paginator_qry ( stages , request . GET . get ( ' page ' ) ) , ' pd ' : previous_data } )
@login_required
@require_http_methods ( [ ' POST ' ] )
@permission_required ( ' recruitment.change_stage ' )
def stage_sequence_update ( request ) :
"""
This is also a ajax method used to update sequence of stage while drag and drop stage in pipeline template ,
"""
stages = json . loads ( json . loads ( request . POST [ ' stages ' ] ) )
sequences = json . loads ( request . POST [ ' newSequences ' ] )
# for index,stage_id in enumerate(stages):
# stage = Stage.objects.get(id=stage_id)
# stage.sequence = sequences[index]
# stage.save()
return JsonResponse ( { ' message ' : ' Congratulations ' } )
@login_required
@permission_required ( ' recruitment.change_stage ' )
@hx_request_required
def stage_update ( request , id ) :
"""
This method is used to update stage , if the managers changed then permission assigned to new managers also
Args :
id : stage_id
"""
stages = Stage . objects . get ( id = id )
form = StageCreationForm ( instance = stages )
if request . method == ' POST ' :
form = StageCreationForm ( request . POST , instance = stages )
if form . is_valid ( ) :
stage = form . save ( )
messages . success ( request , _ ( ' Stage updated. ' ) )
response = render (
request , ' recruitment/recruitment_form.html ' , { ' form ' : form } )
return HttpResponse ( response . content . decode ( ' utf-8 ' ) + ' <script>location.reload();</script> ' )
return render ( request , ' stage/stage_update_form.html ' , { ' form ' : form } )
@login_required
@require_http_methods ( [ ' POST ' ] )
@hx_request_required
def stage_name_update ( request , id ) :
"""
This method is used to update the name of recruitment stage
"""
stage = Stage . objects . get ( id = id )
stage . stage = request . POST [ ' stage ' ]
stage . save ( )
return HttpResponse ( { ' message ' : ' success ' } )
@login_required
@permission_required ( ' recruitment.delete_stage ' )
@require_http_methods ( [ ' POST ' , ' DELETE ' ] )
def stage_delete ( request , id ) :
"""
This method is used to delete stage permanently
Args :
id : stage_id
"""
stage = Stage . objects . get ( id = id )
stage_managers = stage . stage_managers . all ( )
for manager in stage_managers :
all_this_manger = manager . stage_set . all ( )
if len ( all_this_manger ) == 1 :
view_recruitment = Permission . objects . get (
codename = ' view_recruitment ' )
manager . employee_user_id . user_permissions . remove (
view_recruitment . id )
initial_stage_manager = all_this_manger . filter ( stage_type = ' initial ' )
if len ( initial_stage_manager ) == 1 :
add_candidate = Permission . objects . get ( codename = ' add_candidate ' )
change_candidate = Permission . objects . get (
codename = ' change_candidate ' )
manager . employee_user_id . user_permissions . remove ( add_candidate . id )
manager . employee_user_id . user_permissions . remove (
change_candidate . id )
stage . stage_managers . remove ( manager )
try :
stage . delete ( )
messages . success ( request , _ ( ' Stage deleted successfully. ' ) )
except Exception as e :
messages . error ( request , e )
messages . error ( request , _ ( ' You cannot delete this stage ' ) )
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
@login_required
@permission_required ( ' recruitment.add_candidate ' )
def candidate ( request ) :
"""
This method used to create candidate
"""
form = CandidateCreationForm ( )
open_recruitment = Recruitment . objects . filter ( closed = False , is_active = True )
if request . method == ' POST ' :
form = CandidateCreationForm ( request . POST , request . FILES )
if form . is_valid ( ) :
candidate = form . save ( commit = False )
candidate . start_onboard = False
if candidate . stage_id is None :
candidate . stage_id = Stage . objects . filter (
recruitment_id = candidate . recruitment_id , stage_type = " initial " ) . first ( )
candidate . save ( )
messages . success ( request , _ ( ' Candidate added. ' ) )
return redirect ( ' /recruitment/candidate-view ' )
return render ( request , ' candidate/candidate_create_form.html ' , { ' form ' : form , ' open_recruitment ' : open_recruitment } )
@login_required
@permission_required ( ' recruitment.add_candidate ' )
def recruitment_stage_get ( request , id ) :
"""
This method returns all stages as json
Args :
id : recruitment_id
"""
recruitment = Recruitment . objects . get ( id = id )
all_stages = recruitment . stage_set . all ( )
all_stage_json = serializers . serialize ( ' json ' , all_stages )
return JsonResponse ( { ' stages ' : all_stage_json } )
@login_required
@permission_required ( ' recruitment.view_candidate ' )
def candidate_view ( request ) :
"""
This method render all candidate to the template
"""
previous_data = request . environ [ ' QUERY_STRING ' ]
candidates = Candidate . objects . filter ( is_active = True )
filter = CandidateFilter ( queryset = candidates )
return render ( request , ' candidate/candidate_view.html ' , {
' data ' : paginator_qry ( filter . qs , request . GET . get ( ' page ' ) ) ,
' pd ' : previous_data ,
' f ' : filter
} )
@login_required
@permission_required ( ' recruitment.view_candidate ' )
def candidate_filter_view ( request ) :
"""
This method is used for filter , pagination and search candidate .
"""
previous_data = request . environ [ ' QUERY_STRING ' ]
filter = CandidateFilter (
request . GET , queryset = Candidate . objects . filter ( is_active = True ) )
paginator = Paginator ( filter . qs , 24 )
page_number = request . GET . get ( ' page ' )
page_obj = paginator . get_page ( page_number )
return render ( request , ' candidate/candidate_card.html ' , { ' data ' : page_obj , ' pd ' : previous_data } )
@login_required
@permission_required ( ' recruitment.view_candidate ' )
def candidate_search ( request ) :
"""
This method is used to search candidate model and return matching objects
"""
previous_data = request . environ [ ' QUERY_STRING ' ]
search = request . GET . get ( ' search ' )
if search is None :
search = ' '
candidates = Candidate . objects . filter ( name__icontains = search )
candidates = CandidateFilter ( request . GET , queryset = candidates ) . qs
template = ' candidate/candidate_card.html '
if request . GET . get ( ' view ' ) == ' list ' :
template = ' candidate/candidate_list.html '
candidates = sortby ( request , candidates , ' orderby ' )
candidates = paginator_qry ( candidates , request . GET . get ( ' page ' ) )
return render ( request , template , { ' data ' : candidates , ' pd ' : previous_data } )
@login_required
@permission_required ( ' recruitment.view_candidate ' )
def candidate_view_list ( request ) :
"""
This method renders all candidate on candidate_list . html template
"""
previous_data = request . environ [ ' QUERY_STRING ' ]
candidates = Candidate . objects . all ( )
if request . GET . get ( ' is_active ' ) is None :
candidates = candidates . filter ( is_active = True )
candidates = CandidateFilter ( request . GET , queryset = candidates ) . qs
return render ( request , ' candidate/candidate_list.html ' , {
' data ' : paginator_qry ( candidates , request . GET . get ( ' page ' ) ) ,
' pd ' : previous_data }
)
@login_required
@permission_required ( ' recruitment.view_candidate ' )
def candidate_view_card ( request ) :
"""
This method renders all candidate on candidate_card . html template
"""
previous_data = request . environ [ ' QUERY_STRING ' ]
candidates = Candidate . objects . all ( )
if request . GET . get ( ' is_active ' ) is None :
candidates = candidates . filter ( is_active = True )
candidates = CandidateFilter ( request . GET , queryset = candidates ) . qs
return render ( request , ' candidate/candidate_card.html ' , { ' data ' : paginator_qry ( candidates , request . GET . get ( ' page ' ) ) , ' pd ' : previous_data } )
@login_required
@permission_required ( ' recruitment.view_candidate ' )
def candidate_view_individual ( request , id ) :
"""
This method is used to view profile of candidate .
"""
candidate = Candidate . objects . get ( id = id )
return render ( request , ' candidate/individual.html ' , { ' candidate ' : candidate } )
@login_required
@manager_can_enter ( ' recruitment.change_candidate ' )
def candidate_update ( request , id ) :
"""
Used to update or change the candidate
Args :
id : candidate_id
"""
candidate = Candidate . objects . get ( id = id )
form = CandidateCreationForm ( instance = candidate )
if request . method == ' POST ' :
form = CandidateCreationForm (
request . POST , request . FILES , instance = candidate )
if form . is_valid ( ) :
candidate = form . save ( )
if candidate . stage_id is None :
candidate . stage_id = Stage . objects . filter (
recruitment_id = candidate . recruitment_id , stage_type = " initial " ) . first ( )
2023-05-23 16:37:11 +05:30
if candidate . stage_id . recruitment_id != candidate . recruitment_id :
candidate . stage_id = candidate . recruitment_id . stage_set . filter ( stage_type = " initial " ) . first ( )
2023-05-10 15:06:57 +05:30
candidate . save ( )
messages . success ( request , _ ( ' Candidate Updated Successfully. ' ) )
return redirect ( ' /recruitment/candidate-view ' )
return render ( request , ' candidate/candidate_create_form.html ' , { ' form ' : form } )
@login_required
@permission_required ( ' recruitment.delete_candidate ' )
@require_http_methods ( [ ' DELETE ' , ' POST ' ] )
def candidate_delete ( request , id ) :
"""
This method is used to delete candidate permanently
Args :
id : candidate_id
"""
try :
Candidate . objects . get ( id = id ) . delete ( )
messages . success ( request , _ ( ' Candidate deleted successfully. ' ) )
except Exception as e :
messages . error ( request , e )
messages . error ( request , _ ( ' You cannot delete this candidate ' ) )
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
@login_required
@permission_required ( ' recruitment.delete_candidate ' )
def candidate_archive ( request , id ) :
"""
This method is used to archive or un - archive candidates
"""
candidate = Candidate . objects . get ( id = id )
candidate . is_active = not candidate . is_active
candidate . save ( )
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
@login_required
@permission_required ( ' recruitment.delete_candidate ' )
@require_http_methods ( [ ' POST ' ] )
def candidate_bulk_delete ( request ) :
"""
This method is used to bulk delete candidates
"""
ids = request . POST [ ' ids ' ]
ids = json . loads ( ids )
for id in ids :
candidate = Candidate . objects . get ( id = id )
try :
candidate . delete ( )
messages . success ( request , _ ( ' %(candidate)s deleted. ' ) % { ' candidate ' : candidate } )
except Exception as e :
messages . error ( request , _ ( ' You cannot delete %(candidate)s ' ) % { ' candidate ' : candidate } )
messages . error ( request , e )
return JsonResponse ( { ' message ' : ' Success ' } )
@login_required
@permission_required ( ' recruitment.delete_candidate ' )
@require_http_methods ( [ ' POST ' ] )
def candidate_bulk_archive ( request ) :
"""
This method is used to archive / un - archive bulk candidates
"""
ids = request . POST [ ' ids ' ]
ids = json . loads ( ids )
is_active = True
message = ' un-archived '
if request . GET . get ( ' is_active ' ) == ' False ' :
is_active = False
message = ' archived '
for id in ids :
candidate = Candidate . objects . get ( id = id )
candidate . is_active = is_active
candidate . save ( )
messages . success ( request , f ' { candidate } is { message } ' )
return JsonResponse ( { ' message ' : ' Success ' } )
@login_required
@permission_required ( ' recruitment.view_history ' )
def candidate_history ( request , id ) :
"""
This method is used to view candidate stage changes
Args :
id : candidate_id
"""
candidate = Candidate . objects . get ( id = id )
candidate_history = candidate . history . all ( )
return render ( request , ' candidate/candidate_history.html ' , { ' history ' : candidate_history } )
def application_form ( request ) :
"""
This method renders candidate form to create candidate """
form = ApplicationForm ( )
if request . POST :
form = ApplicationForm ( request . POST , request . FILES )
if form . is_valid ( ) :
candidate = form . save ( commit = False )
recruitment = candidate . recruitment_id
stages = recruitment . stage_set . all ( )
if stages . filter ( stage_type = ' initial ' ) . exists ( ) :
candidate . stage_id = stages . filter (
stage_type = ' initial ' ) . first ( )
else :
candidate . stage_id = stages . order_by ( ' sequence ' ) . first ( )
candidate . save ( )
messages . success ( request , _ ( ' Application saved. ' ) )
return HttpResponseRedirect ( request . META . get ( ' HTTP_REFERER ' , ' / ' ) )
return render ( request , ' candidate/application_form.html ' , { ' form ' : form } )
@login_required
@hx_request_required
@manager_can_enter ( ' recruitment.change_candidate ' )
def form_send_mail ( request , id ) :
"""
This method is used to render the bootstrap modal content body form
"""
candidate = Candidate . objects . get ( id = id )
return render ( request , ' pipeline/pipeline_components/send_mail.html ' , { ' cand ' : candidate } )
@login_required
@manager_can_enter ( ' recruitment.change_candidate ' )
def send_acknowledgement ( request ) :
"""
This method is used to send acknowledgement mail to the candidate
"""
try :
to = request . POST . get ( ' to ' )
subject = request . POST . get ( ' subject ' )
bdy = request . POST . get ( ' body ' )
res = send_mail ( subject , bdy , settings . EMAIL_HOST_USER ,
[ to ] , fail_silently = False )
if ( res == 1 ) :
return HttpResponse ( """
< div class = " oh-alert-container " >
< div class = " oh-alert oh-alert--animated oh-alert--success " >
2023-05-23 16:37:11 +05:30
Mail send .
2023-05-10 15:06:57 +05:30
< / div >
< / div >
""" )
except :
pass
return HttpResponse ( """
< div class = " oh-alert-container " >
< div class = " oh-alert oh-alert--animated oh-alert--danger " >
Sorry , Something went wrong .
< / div >
< / div >
"""
)
@login_required
@manager_can_enter ( ' view.recruitment ' )
def dashboard ( request ) :
"""
This method is used to render individual dashboard for recruitment module
"""
candidates = Candidate . objects . all ( )
hired_candidates = candidates . filter ( hired = True )
total_candidates = len ( candidates )
total_hired_candidates = len ( hired_candidates )
hire_ratio = 0
if total_candidates != 0 :
hire_ratio = " %.1f " % ( ( total_hired_candidates / total_candidates ) * 100 )
return render ( request , ' dashboard/dashboard.html ' , {
' total_candidates ' : total_candidates ,
' total_hired_candidates ' : total_hired_candidates ,
' hire_ratio ' : hire_ratio ,
' onboard_candidates ' : hired_candidates . filter ( start_onboard = True ) ,
} )
def stage_type_candidate_count ( rec , type ) :
"""
This method is used find the count of candidate in recruitment
"""
candidates_count = 0
for stage in rec . stage_set . filter ( stage_type = type ) :
candidates_count = candidates_count + \
len ( stage . candidate_set . filter ( is_active = True ) )
return candidates_count
@login_required
@manager_can_enter ( ' view.recruitment ' )
def dashboard_pipeline ( request ) :
"""
This method is used generate recruitment dataset for the dashboard
"""
recruitment = Recruitment . objects . filter ( closed = False )
data_set = [ ]
labels = [ type [ 1 ] for type in Stage . stage_types ]
for rec in recruitment :
data = [ stage_type_candidate_count (
rec , type [ 0 ] ) for type in Stage . stage_types ]
data_set . append ( {
' label ' : rec . __str__ ( ) ,
' data ' : data ,
} )
return JsonResponse ( { ' dataSet ' : data_set , ' labels ' : labels } )