2023-06-06 12:27:41 +05:30
"""
views . py
This module contains the view functions for handling HTTP requests and rendering
responses in your application .
Each view function corresponds to a specific URL route and performs the necessary
actions to handle the request , process data , and generate a response .
This module is part of the recruitment project and is intended to
provide the main entry points for interacting with the application ' s functionality.
"""
2023-12-18 17:20:28 +05:30
2024-05-07 12:23:36 +05:30
import contextlib
import json
2024-09-20 15:39:16 +05:30
import logging
2025-08-29 12:00:36 +05:30
import os
2024-05-07 12:23:36 +05:30
import random
import secrets
2023-09-14 09:55:20 +05:30
from urllib . parse import parse_qs
2024-05-07 12:23:36 +05:30
2023-12-21 16:37:23 +05:30
from django import template
2024-05-07 12:23:36 +05:30
from django . contrib import messages
from django . contrib . auth import login
2023-08-21 17:28:32 +05:30
from django . contrib . auth . models import User
2025-08-29 12:00:36 +05:30
from django . core . files . base import ContentFile
2024-05-07 12:23:36 +05:30
from django . core . mail import EmailMessage , send_mail
from django . core . paginator import Paginator
from django . db . models import ProtectedError
from django . http import HttpResponse , HttpResponseRedirect , JsonResponse
from django . shortcuts import redirect , render
from django . template . loader import render_to_string
2024-06-28 16:37:58 +05:30
from django . urls import reverse
2023-09-20 14:52:02 +05:30
from django . utils . translation import gettext as __
2023-05-10 15:06:57 +05:30
from django . utils . translation import gettext_lazy as _
2025-04-23 22:54:57 +05:30
from django . views . decorators . csrf import csrf_exempt
from django . views . decorators . http import require_http_methods , require_POST
2024-05-07 12:23:36 +05:30
from base . backends import ConfiguredEmailBackend
2024-03-07 11:57:28 +05:30
from base . methods import (
closest_numbers ,
generate_pdf ,
get_key_instances ,
get_pagination ,
sortby ,
)
2024-08-05 14:22:44 +05:30
from base . models import HorillaMailTemplate , JobPosition
2024-05-07 12:23:36 +05:30
from employee . models import Employee , EmployeeBankDetails , EmployeeWorkInformation
from horilla import settings
from horilla . decorators import (
hx_request_required ,
logger ,
login_required ,
permission_required ,
2024-02-20 17:05:43 +05:30
)
2024-06-20 11:47:45 +05:30
from horilla . group_by import group_by_queryset as general_group_by
2025-08-29 12:00:36 +05:30
from horilla_documents . models import Document
2024-05-07 12:23:36 +05:30
from notifications . signals import notify
from onboarding . decorators import (
all_manager_can_enter ,
recruitment_manager_can_enter ,
stage_manager_can_enter ,
)
from onboarding . filters import OnboardingCandidateFilter , OnboardingStageFilter
2023-06-06 12:27:41 +05:30
from onboarding . forms import (
2024-05-07 12:23:36 +05:30
BankDetailsCreationForm ,
EmployeeCreationForm ,
2023-06-06 12:27:41 +05:30
OnboardingCandidateForm ,
2024-01-20 12:51:17 +05:30
OnboardingTaskForm ,
2023-06-06 12:27:41 +05:30
OnboardingViewStageForm ,
2024-05-07 12:23:36 +05:30
OnboardingViewTaskForm ,
UserCreationForm ,
2023-06-06 12:27:41 +05:30
)
from onboarding . models import (
CandidateStage ,
CandidateTask ,
OnboardingPortal ,
2024-05-07 12:23:36 +05:30
OnboardingStage ,
OnboardingTask ,
2023-06-06 12:27:41 +05:30
)
2024-05-07 12:23:36 +05:30
from recruitment . filters import CandidateFilter , CandidateReGroup , RecruitmentFilter
from recruitment . forms import RejectedCandidateForm
2024-08-05 14:22:44 +05:30
from recruitment . models import Candidate , Recruitment , RejectedCandidate
2024-02-15 12:12:23 +05:30
from recruitment . pipeline_grouper import group_by_queryset
2023-05-10 15:06:57 +05:30
2024-09-20 15:39:16 +05:30
logger = logging . getLogger ( __name__ )
2023-05-10 15:06:57 +05:30
@login_required
@hx_request_required
2023-06-06 12:27:41 +05:30
@recruitment_manager_can_enter ( " onboarding.add_onboardingstage " )
def stage_creation ( request , obj_id ) :
2023-05-10 15:06:57 +05:30
"""
function used to create onboarding stage .
Parameters :
request ( HttpRequest ) : The HTTP request object .
2023-06-06 12:27:41 +05:30
obj_id : recruitment id
2023-05-10 15:06:57 +05:30
Returns :
GET : return onboarding stage creation form template
POST : return stage save function
"""
form = OnboardingViewStageForm ( )
if request . method == " POST " :
2023-06-06 12:27:41 +05:30
recruitment = Recruitment . objects . get ( id = obj_id )
2023-05-10 15:06:57 +05:30
form = OnboardingViewStageForm ( request . POST )
if form . is_valid ( ) :
2024-07-17 15:51:11 +05:30
stage_obj = form . save ( )
stage_obj . employee_id . set (
Employee . objects . filter ( id__in = form . data . getlist ( " employee_id " ) )
)
2023-06-06 12:27:41 +05:30
return stage_save ( form , recruitment , request , obj_id )
2023-09-27 13:55:34 +05:30
return render ( request , " onboarding/stage_form.html " , { " form " : form , " id " : obj_id } )
2023-05-10 15:06:57 +05:30
2023-06-06 12:27:41 +05:30
def stage_save ( form , recruitment , request , rec_id ) :
2023-05-10 15:06:57 +05:30
"""
function used to save onboarding stage .
Parameters :
request ( HttpRequest ) : The HTTP request object .
recruitment : recruitment object
2023-06-06 12:27:41 +05:30
rec_id : recruitment id
2023-05-10 15:06:57 +05:30
Returns :
2023-06-06 12:27:41 +05:30
GET : return onboarding view
2023-05-10 15:06:57 +05:30
"""
2024-01-20 12:51:17 +05:30
stage = form . save ( commit = False )
stage . recruitment_id = recruitment
2023-05-10 15:06:57 +05:30
stage . save ( )
messages . success ( request , _ ( " New stage created successfully.. " ) )
users = [ employee . employee_user_id for employee in stage . employee_id . all ( ) ]
notify . send (
request . user . employee_get ,
recipient = users ,
2023-05-18 15:05:28 +05:30
verb = " You are chosen as onboarding stage manager " ,
2023-07-26 12:15:01 +05:30
verb_ar = " لقد تم اختيارك كمدير مرحلة التدريب. " ,
verb_de = " Sie wurden als Onboarding-Stage-Manager ausgewählt. " ,
verb_es = " Ha sido seleccionado/a como responsable de etapa de incorporación. " ,
verb_fr = " Vous avez été choisi(e) en tant que responsable de l ' étape d ' intégration. " ,
2023-05-10 15:06:57 +05:30
icon = " people-circle " ,
2024-06-28 16:37:58 +05:30
redirect = reverse ( " onboarding-view " ) ,
2023-05-10 15:06:57 +05:30
)
2023-06-06 12:27:41 +05:30
response = render (
2023-09-27 13:55:34 +05:30
request , " onboarding/stage_form.html " , { " form " : form , " id " : rec_id }
2023-06-06 12:27:41 +05:30
)
return HttpResponse (
response . content . decode ( " utf-8 " ) + " <script>location.reload();</script> "
)
2023-05-10 15:06:57 +05:30
@login_required
@hx_request_required
2023-06-06 12:27:41 +05:30
@recruitment_manager_can_enter ( " onboarding.change_onboardingstage " )
2023-05-10 15:06:57 +05:30
def stage_update ( request , stage_id , recruitment_id ) :
"""
function used to update onboarding stage .
Parameters :
request ( HttpRequest ) : The HTTP request object .
stage_id : stage id
2023-06-06 12:27:41 +05:30
recruitment_id : recruitment id
2023-05-10 15:06:57 +05:30
Returns :
GET : return onboarding stage update form template
POST : return onboarding view
"""
onboarding_stage = OnboardingStage . objects . get ( id = stage_id )
form = OnboardingViewStageForm ( instance = onboarding_stage )
2023-06-06 12:27:41 +05:30
if request . method == " POST " :
2023-05-10 15:06:57 +05:30
form = OnboardingViewStageForm ( request . POST , instance = onboarding_stage )
if form . is_valid ( ) :
stage = form . save ( )
2024-07-17 15:51:11 +05:30
stage . employee_id . set (
Employee . objects . filter ( id__in = form . data . getlist ( " employee_id " ) )
)
2024-09-04 20:49:54 +05:30
messages . success ( request , _ ( " Stage is updated successfully.. " ) )
2023-06-06 12:27:41 +05:30
users = [ employee . employee_user_id for employee in stage . employee_id . all ( ) ]
2023-05-10 15:06:57 +05:30
notify . send (
request . user . employee_get ,
recipient = users ,
2023-05-18 15:05:28 +05:30
verb = " You are chosen as onboarding stage manager " ,
2023-07-26 12:15:01 +05:30
verb_ar = " لقد تم اختيارك كمدير مرحلة التدريب. " ,
verb_de = " Sie wurden als Onboarding-Stage-Manager ausgewählt. " ,
verb_es = " Ha sido seleccionado/a como responsable de etapa de incorporación. " ,
verb_fr = " Vous avez été choisi(e) en tant que responsable de l ' étape d ' intégration. " ,
2023-05-10 15:06:57 +05:30
icon = " people-circle " ,
2024-06-28 16:37:58 +05:30
redirect = reverse ( " onboarding-view " ) ,
2023-05-10 15:06:57 +05:30
)
2023-06-06 12:27:41 +05:30
response = render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/stage_update.html " ,
2023-06-06 12:27:41 +05:30
{ " form " : form , " stage_id " : stage_id , " recruitment_id " : recruitment_id } ,
)
return HttpResponse (
response . content . decode ( " utf-8 " ) + " <script>location.reload();</script> "
)
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/stage_update.html " ,
2023-06-06 12:27:41 +05:30
{ " form " : form , " stage_id " : stage_id , " recruitment_id " : recruitment_id } ,
)
2023-05-10 15:06:57 +05:30
@login_required
2023-06-06 12:27:41 +05:30
@permission_required ( " onboarding.delete_onboardingstage " )
@recruitment_manager_can_enter ( " onboarding.delete_onboardingstage " )
2023-05-10 15:06:57 +05:30
def stage_delete ( request , stage_id ) :
2023-06-06 12:27:41 +05:30
"""
2023-05-10 15:06:57 +05:30
function used to delete onboarding stage .
Parameters :
request ( HttpRequest ) : The HTTP request object .
stage_id : stage id
Returns :
GET : return onboarding view
"""
2023-09-15 11:13:26 +05:30
try :
OnboardingStage . objects . get ( id = stage_id ) . delete ( )
messages . success ( request , _ ( " The stage deleted successfully... " ) )
2023-09-20 14:52:02 +05:30
2023-09-15 11:13:26 +05:30
except OnboardingStage . DoesNotExist :
messages . error ( request , _ ( " Stage not found. " ) )
except ProtectedError :
2023-05-10 15:06:57 +05:30
messages . error ( request , _ ( " There are candidates in this stage... " ) )
2023-08-31 16:45:36 +05:30
return HttpResponseRedirect ( request . META . get ( " HTTP_REFERER " , " / " ) )
2023-05-10 15:06:57 +05:30
@login_required
@hx_request_required
2023-06-06 12:27:41 +05:30
@stage_manager_can_enter ( " onboarding.add_onboardingtask " )
2024-01-20 12:51:17 +05:30
def task_creation ( request ) :
2023-05-10 15:06:57 +05:30
"""
function used to create onboarding task .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
GET : return onboarding task creation form template
POST : return onboarding view
"""
2024-01-23 15:29:05 +05:30
stage_id = request . GET . get ( " stage_id " )
2024-01-20 12:51:17 +05:30
stage = OnboardingStage . objects . get ( id = stage_id )
2024-01-23 15:29:05 +05:30
form = OnboardingViewTaskForm ( initial = { " stage_id " : stage } )
2024-01-20 12:51:17 +05:30
2023-05-10 15:06:57 +05:30
if request . method == " POST " :
2024-01-23 15:29:05 +05:30
form_data = OnboardingViewTaskForm ( request . POST , initial = { " stage_id " : stage } )
2023-05-10 15:06:57 +05:30
if form_data . is_valid ( ) :
2024-01-23 15:29:05 +05:30
candidates = form_data . cleaned_data [ " candidates " ]
stage_id = form_data . cleaned_data [ " stage_id " ]
managers = form_data . cleaned_data [ " managers " ]
title = form_data . cleaned_data [ " task_title " ]
onboarding_task = OnboardingTask ( task_title = title , stage_id = stage_id )
2024-01-20 12:51:17 +05:30
onboarding_task . save ( )
onboarding_task . employee_id . set ( managers )
onboarding_task . candidates . set ( candidates )
if candidates :
for cand in candidates :
2024-01-23 15:29:05 +05:30
task = CandidateTask (
candidate_id = cand ,
stage_id = stage_id ,
onboarding_task_id = onboarding_task ,
)
2024-01-20 12:51:17 +05:30
task . save ( )
2024-01-23 15:29:05 +05:30
users = [
manager . employee_user_id
for manager in onboarding_task . employee_id . all ( )
]
2023-05-10 15:06:57 +05:30
notify . send (
request . user . employee_get ,
recipient = users ,
2023-07-26 12:15:01 +05:30
verb = " You are chosen as an onboarding task manager " ,
verb_ar = " لقد تم اختيارك كمدير مهام التدريب. " ,
verb_de = " Sie wurden als Onboarding-Aufgabenmanager ausgewählt. " ,
verb_es = " Ha sido seleccionado/a como responsable de tareas de incorporación. " ,
verb_fr = " Vous avez été choisi(e) en tant que responsable des tâches d ' intégration. " ,
2023-05-10 15:06:57 +05:30
icon = " people-circle " ,
2024-06-28 16:37:58 +05:30
redirect = reverse ( " onboarding-view " ) ,
2023-05-10 15:06:57 +05:30
)
2024-01-20 12:51:17 +05:30
messages . success ( request , _ ( " New task created successfully... " ) )
2025-05-14 17:19:05 +05:30
return HttpResponse ( status = 204 , headers = { " HX-Refresh " : " true " } )
2024-01-23 15:29:05 +05:30
return render (
request , " onboarding/task_form.html " , { " form " : form , " stage_id " : stage_id }
)
2023-05-10 15:06:57 +05:30
@login_required
@hx_request_required
2023-06-06 12:27:41 +05:30
@stage_manager_can_enter ( " onboarding.change_onboardingtask " )
2024-01-23 15:29:05 +05:30
def task_update (
request ,
task_id ,
) :
2023-05-10 15:06:57 +05:30
"""
function used to update onboarding task .
Parameters :
request ( HttpRequest ) : The HTTP request object .
task_id : task id
Returns :
GET : return onboarding task update form template
POST : return onboarding view
"""
onboarding_task = OnboardingTask . objects . get ( id = task_id )
2025-05-14 17:19:05 +05:30
form = OnboardingTaskForm ( instance = onboarding_task )
2023-06-06 12:27:41 +05:30
if request . method == " POST " :
2024-01-20 12:51:17 +05:30
form = OnboardingTaskForm ( request . POST , instance = onboarding_task )
2023-05-10 15:06:57 +05:30
if form . is_valid ( ) :
task = form . save ( )
2024-07-17 15:51:11 +05:30
task . employee_id . set (
Employee . objects . filter ( id__in = form . data . getlist ( " employee_id " ) )
)
2024-01-20 12:51:17 +05:30
for cand_task in onboarding_task . candidatetask_set . all ( ) :
if cand_task . candidate_id not in task . candidates . all ( ) :
cand_task . delete ( )
else :
cand_task . stage_id = task . stage_id
2024-09-04 20:49:54 +05:30
messages . success ( request , _ ( " Task updated successfully.. " ) )
2023-06-06 12:27:41 +05:30
users = [ employee . employee_user_id for employee in task . employee_id . all ( ) ]
2023-05-10 15:06:57 +05:30
notify . send (
request . user . employee_get ,
recipient = users ,
2023-07-26 12:15:01 +05:30
verb = " You are chosen as an onboarding task manager " ,
verb_ar = " لقد تم اختيارك كمدير مهام التدريب. " ,
verb_de = " Sie wurden als Onboarding-Aufgabenmanager ausgewählt. " ,
verb_es = " Ha sido seleccionado/a como responsable de tareas de incorporación. " ,
verb_fr = " Vous avez été choisi(e) en tant que responsable des tâches d ' intégration. " ,
2023-05-10 15:06:57 +05:30
icon = " people-circle " ,
2024-06-28 16:37:58 +05:30
redirect = reverse ( " onboarding-view " ) ,
2023-05-10 15:06:57 +05:30
)
2025-05-14 17:19:05 +05:30
return HttpResponse ( status = 204 , headers = { " HX-Refresh " : " true " } )
2023-06-06 12:27:41 +05:30
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/task_update.html " ,
2024-01-23 15:29:05 +05:30
{
" form " : form ,
" task_id " : task_id ,
} ,
2023-06-06 12:27:41 +05:30
)
2023-05-10 15:06:57 +05:30
@login_required
2023-06-06 12:27:41 +05:30
@permission_required ( " onboarding.delete_onboardingtask " )
@stage_manager_can_enter ( " onboarding.delete_onboardingtask " )
2023-05-10 15:06:57 +05:30
def task_delete ( request , task_id ) :
"""
function used to delete onboarding task .
Parameters :
request ( HttpRequest ) : The HTTP request object .
task_id : task id
Returns :
GET : return onboarding view
"""
2023-09-15 11:13:26 +05:30
try :
OnboardingTask . objects . get ( id = task_id ) . delete ( )
messages . success ( request , _ ( " The task deleted successfully... " ) )
except OnboardingTask . DoesNotExist :
messages . error ( request , _ ( " Task not found. " ) )
except ProtectedError :
2023-09-20 14:52:02 +05:30
messages . error (
request ,
_ (
" You cannot delete this task because some candidates are associated with it. "
) ,
)
2023-05-10 15:06:57 +05:30
return redirect ( onboarding_view )
@login_required
2023-06-06 12:27:41 +05:30
@permission_required ( " recruitment.add_candidate " )
2023-05-10 15:06:57 +05:30
def candidate_creation ( request ) :
"""
function used to create hired candidates .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
GET : return candidate creation form template
POST : return candidate view
"""
form = OnboardingCandidateForm ( )
2023-06-06 12:27:41 +05:30
if request . method == " POST " :
2023-05-10 15:06:57 +05:30
form = OnboardingCandidateForm ( request . POST , request . FILES )
if form . is_valid ( ) :
candidate = form . save ( )
candidate . hired = True
candidate . save ( )
2023-06-06 12:27:41 +05:30
messages . success ( request , _ ( " New candidate created successfully.. " ) )
2023-05-10 15:06:57 +05:30
return redirect ( candidates_view )
2023-09-27 13:55:34 +05:30
return render ( request , " onboarding/candidate_creation.html " , { " form " : form } )
2023-05-10 15:06:57 +05:30
@login_required
2023-06-06 12:27:41 +05:30
@permission_required ( " recruitment.change_candidate " )
def candidate_update ( request , obj_id ) :
2023-05-10 15:06:57 +05:30
"""
function used to update hired candidates .
Parameters :
request ( HttpRequest ) : The HTTP request object .
2023-06-06 12:27:41 +05:30
obj_id : recruitment id
2023-05-10 15:06:57 +05:30
Returns :
GET : return candidate update form template
POST : return candidate view
"""
2023-06-06 12:27:41 +05:30
candidate = Candidate . objects . get ( id = obj_id )
2023-05-10 15:06:57 +05:30
form = OnboardingCandidateForm ( instance = candidate )
2023-06-06 12:27:41 +05:30
if request . method == " POST " :
form = OnboardingCandidateForm ( request . POST , request . FILES , instance = candidate )
2023-05-10 15:06:57 +05:30
if form . is_valid ( ) :
form . save ( )
2024-09-04 20:49:54 +05:30
messages . success ( request , _ ( " Candidate detail is updated successfully.. " ) )
2023-05-10 15:06:57 +05:30
return redirect ( candidates_view )
2023-09-27 13:55:34 +05:30
return render ( request , " onboarding/candidate_update.html " , { " form " : form } )
2023-05-10 15:06:57 +05:30
@login_required
2025-07-07 14:19:54 +05:30
@permission_required ( " onboarding.delete_onboardingcandidate " )
2023-06-06 12:27:41 +05:30
def candidate_delete ( request , obj_id ) :
2023-05-10 15:06:57 +05:30
"""
function used to delete hired candidates .
Parameters :
request ( HttpRequest ) : The HTTP request object .
2025-07-07 14:19:54 +05:30
obj_id : candidate id
2023-05-10 15:06:57 +05:30
Returns :
GET : return candidate view
"""
2023-09-15 11:13:26 +05:30
try :
Candidate . objects . get ( id = obj_id ) . delete ( )
messages . success ( request , _ ( " Candidate deleted successfully.. " ) )
except Candidate . DoesNotExist :
messages . error ( request , _ ( " Candidate not found. " ) )
2023-09-20 14:52:02 +05:30
except ProtectedError as e :
models_verbose_name_sets = set ( )
for obj in e . protected_objects :
models_verbose_name_sets . add ( __ ( obj . _meta . verbose_name ) )
models_verbose_name_str = ( " , " ) . join ( models_verbose_name_sets )
messages . error (
request ,
_ (
" You cannot delete this candidate. The candidate is included in the {} " . format (
models_verbose_name_str
)
) ,
)
2023-05-10 15:06:57 +05:30
return redirect ( candidates_view )
2023-11-08 16:12:02 +05:30
2023-10-19 12:37:23 +05:30
@login_required
2024-05-30 10:07:39 +05:30
@hx_request_required
2024-02-05 13:53:16 +05:30
@all_manager_can_enter ( " onboarding.view_candidatestage " )
2023-11-08 16:12:02 +05:30
def candidates_single_view ( request , id , * * kwargs ) :
2023-11-06 12:04:59 +05:30
"""
2023-11-08 16:12:02 +05:30
Candidate individual view for the onboarding candidates
2023-11-06 12:04:59 +05:30
"""
candidate = Candidate . objects . get ( id = id )
2023-10-19 12:37:23 +05:30
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 ( )
2023-11-08 16:12:02 +05:30
recruitment = candidate . recruitment_id
2023-10-19 12:37:23 +05:30
choices = CandidateTask . choice
context = {
2023-11-08 16:12:02 +05:30
" recruitment " : recruitment ,
" choices " : choices ,
" candidate " : candidate ,
2024-01-23 15:29:05 +05:30
" single_view " : True ,
2023-11-08 16:12:02 +05:30
}
2024-02-29 12:23:15 +05:30
requests_ids_json = request . GET . get ( " requests_ids " )
if requests_ids_json :
requests_ids = json . loads ( requests_ids_json )
previous_id , next_id = closest_numbers ( requests_ids , id )
context [ " requests_ids " ] = requests_ids_json
context [ " previous " ] = previous_id
context [ " next " ] = next_id
2023-10-19 12:37:23 +05:30
return render (
request ,
" onboarding/single_view.html " ,
context ,
)
2023-05-10 15:06:57 +05:30
def paginator_qry ( qryset , page_number ) :
"""
function used to paginate query set
"""
2024-01-20 16:37:12 +05:30
paginator = Paginator ( qryset , get_pagination ( ) )
2023-05-10 15:06:57 +05:30
qryset = paginator . get_page ( page_number )
return qryset
@login_required
2025-07-07 14:19:54 +05:30
@permission_required ( perm = " onboarding.view_onboardingcandidate " )
2023-05-10 15:06:57 +05:30
def candidates_view ( request ) :
"""
function used to view hired candidates .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
GET : return candidate view template
"""
2023-12-19 13:02:15 +05:30
queryset = Candidate . objects . filter (
2024-03-25 16:16:45 +05:30
is_active = True ,
2023-12-19 13:02:15 +05:30
hired = True ,
recruitment_id__closed = False ,
)
2024-03-25 16:16:45 +05:30
candidate_filter_obj = CandidateFilter ( request . GET , queryset )
2023-09-12 11:59:58 +05:30
previous_data = request . GET . urlencode ( )
2023-06-06 12:27:41 +05:30
page_number = request . GET . get ( " page " )
2024-03-25 16:16:45 +05:30
page_obj = paginator_qry ( candidate_filter_obj . qs , page_number )
2024-08-05 14:22:44 +05:30
mail_templates = HorillaMailTemplate . objects . all ( )
2024-03-25 16:16:45 +05:30
data_dict = parse_qs ( previous_data )
get_key_instances ( Candidate , data_dict )
2023-06-06 12:27:41 +05:30
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/candidates_view.html " ,
2023-06-06 12:27:41 +05:30
{
" candidates " : page_obj ,
" form " : candidate_filter_obj . form ,
" pd " : previous_data ,
2024-03-07 11:57:28 +05:30
" gp_fields " : CandidateReGroup . fields ,
2023-12-21 16:37:23 +05:30
" mail_templates " : mail_templates ,
" hired_candidates " : queryset ,
2024-03-27 14:20:20 +05:30
" filter_dict " : data_dict ,
2023-06-06 12:27:41 +05:30
} ,
)
2023-09-11 15:37:32 +05:30
2023-08-31 16:45:36 +05:30
@login_required
@permission_required ( perm = " recruitment.view_candidate " )
def hired_candidate_view ( request ) :
2023-09-12 11:59:58 +05:30
previous_data = request . GET . urlencode ( )
2023-12-19 13:02:15 +05:30
candidates = Candidate . objects . filter (
hired = True ,
recruitment_id__closed = False ,
)
2023-08-31 16:45:36 +05:30
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 ,
} ,
)
2023-05-10 15:06:57 +05:30
2023-09-11 15:37:32 +05:30
2023-05-10 15:06:57 +05:30
@login_required
2024-05-30 10:07:39 +05:30
@hx_request_required
2025-07-07 14:19:54 +05:30
@permission_required ( perm = " onboarding.view_onboardingcandidate " )
2023-05-10 15:06:57 +05:30
def candidate_filter ( request ) :
"""
function used to filter hired candidates .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
2023-06-06 12:27:41 +05:30
GET : return candidate view template
2023-05-10 15:06:57 +05:30
"""
2023-12-19 13:02:15 +05:30
queryset = Candidate . objects . filter (
2024-03-25 16:16:45 +05:30
is_active = True ,
2023-12-19 13:02:15 +05:30
hired = True ,
recruitment_id__closed = False ,
)
2024-02-03 13:59:47 +05:30
candidates = CandidateFilter ( request . GET , queryset ) . qs
2023-09-12 11:59:58 +05:30
previous_data = request . GET . urlencode ( )
2023-06-06 12:27:41 +05:30
page_number = request . GET . get ( " page " )
2023-09-14 09:55:20 +05:30
data_dict = parse_qs ( previous_data )
get_key_instances ( Candidate , data_dict )
2024-02-03 13:59:47 +05:30
candidates = sortby ( request , candidates , " orderby " )
2024-02-27 00:54:41 +05:30
field = request . GET . get ( " field " )
template = " onboarding/candidates.html "
if field != " " and field is not None :
template = " onboarding/group_by.html "
2024-03-07 11:57:28 +05:30
candidates = general_group_by (
candidates , field , request . GET . get ( " page " ) , " page "
)
2024-02-03 13:59:47 +05:30
page_obj = paginator_qry ( candidates , page_number )
2023-06-06 12:27:41 +05:30
return render (
request ,
2024-02-27 00:54:41 +05:30
template ,
2023-09-14 09:55:20 +05:30
{ " candidates " : page_obj , " pd " : previous_data , " filter_dict " : data_dict } ,
2023-06-06 12:27:41 +05:30
)
2023-05-10 15:06:57 +05:30
@login_required
2023-12-19 13:02:15 +05:30
@all_manager_can_enter ( " recruitment.view_recruitment " )
2023-05-10 15:06:57 +05:30
def email_send ( request ) :
"""
function used to send onboarding portal for hired candidates .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
2023-08-31 16:45:36 +05:30
GET : return json response
2023-05-10 15:06:57 +05:30
"""
2023-12-18 17:20:28 +05:30
host = request . get_host ( )
protocol = " https " if request . is_secure ( ) else " http "
2023-12-21 16:37:23 +05:30
candidates = request . POST . getlist ( " ids " )
other_attachments = request . FILES . getlist ( " other_attachments " )
template_attachment_ids = request . POST . getlist ( " template_attachment_ids " )
2024-03-07 11:57:28 +05:30
email_backend = ConfiguredEmailBackend ( )
2023-12-21 16:37:23 +05:30
if not candidates :
2024-08-27 17:36:33 +05:30
messages . info ( request , " Please choose candidates " )
2023-12-21 16:37:23 +05:30
return HttpResponse ( " <script>window.location.reload()</script> " )
bodys = list (
2024-08-05 14:22:44 +05:30
HorillaMailTemplate . objects . filter ( id__in = template_attachment_ids ) . values_list (
" body " , flat = True
)
2023-12-21 16:37:23 +05:30
)
attachments_other = [ ]
for file in other_attachments :
attachments_other . append ( ( file . name , file . read ( ) , file . content_type ) )
file . close ( )
2023-12-19 13:02:15 +05:30
for cand_id in candidates :
2023-12-21 16:37:23 +05:30
attachments = list ( set ( attachments_other ) | set ( [ ] ) )
2023-06-06 12:27:41 +05:30
candidate = Candidate . objects . get ( id = cand_id )
2025-04-02 14:31:20 +05:30
if not request . GET . get ( " no_portal " ) :
2025-03-26 14:58:02 +05:30
if candidate . converted_employee_id :
messages . info (
request , _ ( f " { candidate } has already been converted to employee. " )
2023-12-21 16:37:23 +05:30
)
2025-03-26 14:58:02 +05:30
continue
for html in bodys :
# due to not having solid template we first need to pass the context
template_bdy = template . Template ( html )
context = template . Context (
{ " instance " : candidate , " self " : request . user . employee_get }
)
render_bdy = template_bdy . render ( context )
attachments . append (
(
" Document " ,
generate_pdf (
render_bdy , { } , path = False , title = " Document "
) . content ,
" application/pdf " ,
)
)
token = secrets . token_hex ( 15 )
existing_portal = OnboardingPortal . objects . filter ( candidate_id = candidate )
if existing_portal . exists ( ) :
new_portal = existing_portal . first ( )
new_portal . token = token
new_portal . used = False
new_portal . count = 0
new_portal . profile = None
new_portal . save ( )
else :
OnboardingPortal ( candidate_id = candidate , token = token ) . save ( )
html_message = render_to_string (
" onboarding/mail_templates/default.html " ,
{
" portal " : f " { protocol } :// { host } /onboarding/user-creation/ { token } " ,
" instance " : candidate ,
" host " : host ,
" protocol " : protocol ,
} ,
request = request ,
2023-12-21 16:37:23 +05:30
)
2025-03-26 14:58:02 +05:30
email = EmailMessage (
subject = f " Hello { candidate . name } , Congratulations on your selection! " ,
body = html_message ,
to = [ candidate . email ] ,
)
email . content_subtype = " html "
email . attachments = attachments
try :
email . send ( )
# to check ajax or not
messages . success ( request , " Portal link sent to the candidate " )
except Exception as e :
logger . error ( e )
messages . error ( request , f " Mail not send to { candidate . name } " )
candidate . start_onboard = True
candidate . save ( )
2024-02-03 13:59:47 +05:30
try :
onboarding_candidate = CandidateStage ( )
onboarding_candidate . onboarding_stage_id = (
candidate . recruitment_id . onboarding_stage . first ( )
)
onboarding_candidate . candidate_id = candidate
onboarding_candidate . save ( )
2025-03-26 14:58:02 +05:30
messages . success ( request , " Candidate Added to Onboarding Stage " )
2024-02-26 20:14:38 +05:30
except Exception as e :
logger . error ( e )
2024-02-03 13:59:47 +05:30
2023-12-21 16:37:23 +05:30
return HttpResponse ( " <script>window.location.reload()</script> " )
2023-05-10 15:06:57 +05:30
2024-02-20 17:05:43 +05:30
def onboarding_query_grouper ( request , queryset ) :
2024-02-15 12:12:23 +05:30
"""
This method is used to make group of the onboarding records
"""
groups = [ ]
for rec in queryset :
2024-02-29 12:23:15 +05:30
employees = [ ]
2024-02-20 17:05:43 +05:30
stages = OnboardingStageFilter (
request . GET , queryset = rec . onboarding_stage . all ( )
) . qs . order_by ( " sequence " )
2024-02-15 12:12:23 +05:30
all_stages_grouper = [ ]
data = { " recruitment " : rec , " stages " : [ ] }
2024-02-20 17:05:43 +05:30
for stage in stages :
all_stages_grouper . append ( { " grouper " : stage , " list " : [ ] } )
2024-02-15 12:12:23 +05:30
stage_candidates = OnboardingCandidateFilter (
request . GET ,
2024-02-20 17:05:43 +05:30
stage . candidate . filter (
2024-02-15 12:12:23 +05:30
candidate_id__is_active = True ,
) ,
2024-02-20 17:05:43 +05:30
) . qs . order_by ( " sequence " )
2024-02-15 12:12:23 +05:30
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
2024-02-29 12:23:15 +05:30
employees = employees + [
employee . candidate_id . id for employee in stage . candidate . all ( )
]
2024-02-20 17:05:43 +05:30
ordered_data = [ ]
# combining un used groups in to the grouper
groupers = data [ " stages " ]
for stage in stages :
found = False
for grouper in groupers :
if grouper [ " grouper " ] == stage :
ordered_data . append ( grouper )
found = True
2024-02-22 22:57:56 +05:30
break
2024-02-20 17:05:43 +05:30
if not found :
ordered_data . append ( { " grouper " : stage } )
data = {
" recruitment " : rec ,
" stages " : ordered_data ,
2024-02-29 12:23:15 +05:30
" employee_ids " : employees ,
2024-02-20 17:05:43 +05:30
}
2024-02-15 12:12:23 +05:30
groups . append ( data )
return groups
2023-05-10 15:06:57 +05:30
@login_required
2025-07-07 14:19:54 +05:30
@all_manager_can_enter ( " onboarding.view_onboardingstage " )
2023-05-10 15:06:57 +05:30
def onboarding_view ( request ) :
"""
function used to view onboarding main view .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
GET : return onboarding view template
"""
2024-02-15 12:12:23 +05:30
filter_obj = RecruitmentFilter ( request . GET )
# is active filteration not providing on pipeline
2024-04-16 12:23:14 +05:30
recruitments = filter_obj . qs
2025-07-07 14:19:54 +05:30
if not request . user . has_perm ( " onboarding.view_onboardingstage " ) :
2024-04-30 12:43:43 +05:30
recruitments = recruitments . filter (
is_active = True , recruitment_managers__in = [ request . user . employee_get ]
) | recruitments . filter (
onboarding_stage__employee_id__in = [ request . user . employee_get ]
)
2024-04-16 12:23:14 +05:30
employee_tasks = request . user . employee_get . onboarding_task . all ( )
for task in employee_tasks :
if task . stage_id and task . stage_id . recruitment_id not in recruitments :
2024-05-07 12:23:36 +05:30
recruitments = recruitments | filter_obj . qs . filter (
id = task . stage_id . recruitment_id . id
)
recruitments = recruitments . filter ( is_active = True ) . distinct ( )
2024-02-15 12:12:23 +05:30
status = request . GET . get ( " closed " )
2024-06-14 14:47:23 +05:30
if not status :
recruitments = recruitments . filter ( closed = False )
2023-08-31 16:45:36 +05:30
2023-05-10 15:06:57 +05:30
onboarding_stages = OnboardingStage . objects . all ( )
2023-08-31 16:45:36 +05:30
choices = CandidateTask . choice
2024-01-03 10:13:46 +05:30
previous_data = request . GET . urlencode ( )
2024-02-20 17:05:43 +05:30
paginator = Paginator ( recruitments . order_by ( " id " ) , 4 )
2024-01-03 10:13:46 +05:30
page_number = request . GET . get ( " page " )
page_obj = paginator . get_page ( page_number )
2024-02-20 17:05:43 +05:30
groups = onboarding_query_grouper ( request , page_obj )
2024-02-15 12:12:23 +05:30
for item in groups :
setattr ( item [ " recruitment " ] , " stages " , item [ " stages " ] )
2024-02-29 12:23:15 +05:30
setattr ( item [ " recruitment " ] , " employee_ids " , item [ " employee_ids " ] )
2024-02-15 12:12:23 +05:30
filter_dict = parse_qs ( request . GET . urlencode ( ) )
for key , val in filter_dict . copy ( ) . items ( ) :
if val [ 0 ] == " unknown " or key == " view " :
del filter_dict [ key ]
2023-06-06 12:27:41 +05:30
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/onboarding_view.html " ,
2023-06-06 12:27:41 +05:30
{
2024-01-03 10:13:46 +05:30
" recruitments " : page_obj ,
2024-02-15 12:12:23 +05:30
" rec_filter_obj " : filter_obj ,
2023-06-06 12:27:41 +05:30
" onboarding_stages " : onboarding_stages ,
" choices " : choices ,
2024-02-15 12:12:23 +05:30
" filter_dict " : filter_dict ,
2023-09-11 15:37:32 +05:30
" status " : status ,
2024-01-03 10:13:46 +05:30
" pd " : previous_data ,
2023-06-06 12:27:41 +05:30
} ,
)
2023-05-10 15:06:57 +05:30
2023-08-31 16:45:36 +05:30
@login_required
2025-07-07 14:19:54 +05:30
@all_manager_can_enter ( " onboarding.view_onboardingstage " )
2023-08-31 16:45:36 +05:30
def kanban_view ( request ) :
2024-06-28 16:37:58 +05:30
# filter_obj = RecruitmentFilter(request.GET)
# # is active filteration not providing on pipeline
# recruitments = filter_obj.qs.filter(is_active=True)
2024-02-15 12:12:23 +05:30
filter_obj = RecruitmentFilter ( request . GET )
# is active filteration not providing on pipeline
2024-06-28 16:37:58 +05:30
recruitments = filter_obj . qs
2025-07-07 14:19:54 +05:30
if not request . user . has_perm ( " onboarding.view_onboardingstage " ) :
2024-06-28 16:37:58 +05:30
recruitments = recruitments . filter (
is_active = True , recruitment_managers__in = [ request . user . employee_get ]
) | recruitments . filter (
onboarding_stage__employee_id__in = [ request . user . employee_get ]
)
employee_tasks = request . user . employee_get . onboarding_task . all ( )
for task in employee_tasks :
if task . stage_id and task . stage_id . recruitment_id not in recruitments :
recruitments = recruitments | filter_obj . qs . filter (
id = task . stage_id . recruitment_id . id
)
recruitments = recruitments . filter ( is_active = True ) . distinct ( )
2024-02-20 17:05:43 +05:30
2024-02-15 12:12:23 +05:30
status = request . GET . get ( " closed " )
2024-06-28 16:37:58 +05:30
if not status :
recruitments = recruitments . filter ( closed = False )
2024-02-22 13:55:54 +05:30
2023-08-31 16:45:36 +05:30
onboarding_stages = OnboardingStage . objects . all ( )
choices = CandidateTask . choice
stage_form = OnboardingViewStageForm ( )
2024-01-03 10:13:46 +05:30
previous_data = request . GET . urlencode ( )
2024-01-23 15:29:05 +05:30
filter_obj = RecruitmentFilter ( request . GET , queryset = recruitments )
2024-02-15 12:12:23 +05:30
paginator = Paginator ( recruitments , 4 )
2024-01-03 10:13:46 +05:30
page_number = request . GET . get ( " page " )
page_obj = paginator . get_page ( page_number )
2024-02-20 17:05:43 +05:30
groups = onboarding_query_grouper ( request , page_obj )
2024-02-15 12:12:23 +05:30
for item in groups :
setattr ( item [ " recruitment " ] , " stages " , item [ " stages " ] )
filter_dict = parse_qs ( request . GET . urlencode ( ) )
for key , val in filter_dict . copy ( ) . items ( ) :
if val [ 0 ] == " unknown " or key == " view " :
del filter_dict [ key ]
2024-01-03 10:13:46 +05:30
2023-08-31 16:45:36 +05:30
return render (
request ,
" onboarding/kanban/kanban.html " ,
{
2024-01-03 10:13:46 +05:30
" recruitments " : page_obj ,
2024-02-15 12:12:23 +05:30
" rec_filter_obj " : filter_obj ,
2023-08-31 16:45:36 +05:30
" onboarding_stages " : onboarding_stages ,
" choices " : choices ,
2024-02-15 12:12:23 +05:30
" filter_dict " : filter_dict ,
2023-08-31 16:45:36 +05:30
" stage_form " : stage_form ,
2023-09-11 15:37:32 +05:30
" status " : status ,
" choices " : choices ,
2024-01-23 15:29:05 +05:30
" pd " : previous_data ,
2024-02-15 12:12:23 +05:30
" card " : True ,
2023-08-31 16:45:36 +05:30
} ,
2023-09-11 15:37:32 +05:30
)
2023-08-31 16:45:36 +05:30
2024-06-19 12:07:25 +05:30
portal_user = { }
2023-05-10 15:06:57 +05:30
def user_creation ( request , token ) :
"""
function used to create user account in onboarding portal .
Parameters :
request ( HttpRequest ) : The HTTP request object .
token : random generated onboarding portal token
Returns :
GET : return user creation form template
POST : return user_save function
"""
try :
onboarding_portal = OnboardingPortal . objects . get ( token = token )
2024-06-19 12:07:25 +05:30
if not onboarding_portal or onboarding_portal . used is True :
return render ( request , " 404.html " )
if onboarding_portal . count == 3 :
return redirect ( " employee-bank-details " , token )
2023-08-21 17:28:32 +05:30
candidate = onboarding_portal . candidate_id
user = User . objects . filter ( username = candidate . email ) . first ( )
form = UserCreationForm ( instance = user )
2023-05-10 15:06:57 +05:30
try :
2023-06-06 12:27:41 +05:30
if request . method == " POST " :
2023-08-21 17:28:32 +05:30
form = UserCreationForm ( request . POST , instance = user )
2023-05-10 15:06:57 +05:30
if form . is_valid ( ) :
return user_save ( form , onboarding_portal , request , token )
2023-06-06 12:27:41 +05:30
except Exception :
messages . error ( request , _ ( " User with email-id already exists.. " ) )
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/user_creation.html " ,
2023-06-06 12:27:41 +05:30
{
" form " : form ,
" company " : onboarding_portal . candidate_id . recruitment_id . company_id ,
} ,
)
except Exception as error :
return HttpResponse ( error )
2023-05-10 15:06:57 +05:30
def user_save ( form , onboarding_portal , request , token ) :
"""
function used to save user .
Parameters :
request ( HttpRequest ) : The HTTP request object .
onboarding_portal : onboarding portal object
token : random generated onboarding portal token
Returns :
GET : return profile view
"""
user = form . save ( commit = False )
user . username = onboarding_portal . candidate_id . email
2024-06-19 12:07:25 +05:30
session_key = request . session . session_key
portal_user [ session_key ] = user
2023-08-21 17:28:32 +05:30
onboarding_portal . count = 1
2024-06-19 12:07:25 +05:30
onboarding_portal . save ( )
2023-05-10 15:06:57 +05:30
messages . success ( request , _ ( " Account created successfully.. " ) )
2023-06-06 12:27:41 +05:30
return redirect ( " profile-view " , token )
2023-05-10 15:06:57 +05:30
def profile_view ( request , token ) :
"""
function used to view user profile .
Parameters :
request ( HttpRequest ) : The HTTP request object .
token : random generated onboarding portal token
Returns :
GET : return user profile template
POST : update profile image of the user
"""
2023-08-21 17:28:32 +05:30
onboarding_portal = OnboardingPortal . objects . filter ( token = token ) . first ( )
if onboarding_portal is None :
2024-06-19 12:07:25 +05:30
return render ( request , " 404.html " )
2023-08-21 17:28:32 +05:30
candidate = onboarding_portal . candidate_id
2023-06-06 12:27:41 +05:30
if request . method == " POST " :
profile = request . FILES . get ( " profile " )
2023-05-10 15:06:57 +05:30
if profile is not None :
candidate . profile = profile
2024-06-19 12:07:25 +05:30
onboarding_portal . profile = profile
2023-08-21 17:28:32 +05:30
onboarding_portal . count = 2
2024-06-19 12:07:25 +05:30
onboarding_portal . save ( )
2023-06-06 12:27:41 +05:30
messages . success ( request , _ ( " Profile picture updated successfully.. " ) )
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/profile_view.html " ,
2023-06-06 12:27:41 +05:30
{
" candidate " : candidate ,
2024-06-19 12:07:25 +05:30
" profile " : onboarding_portal . profile ,
2023-06-06 12:27:41 +05:30
" token " : token ,
" company " : candidate . recruitment_id . company_id ,
} ,
)
2023-05-10 15:06:57 +05:30
def employee_creation ( request , token ) :
"""
function used to create employee .
Parameters :
request ( HttpRequest ) : The HTTP request object .
token : random generated onboarding portal token .
Returns :
GET : return employee creation profile template .
POST : return employee bank detail creation template .
"""
2023-08-21 17:28:32 +05:30
onboarding_portal = OnboardingPortal . objects . filter ( token = token ) . first ( )
if onboarding_portal is None :
2024-06-19 12:07:25 +05:30
return render ( request , " 404.html " )
2023-08-21 17:28:32 +05:30
candidate = onboarding_portal . candidate_id
initial = {
" employee_first_name " : candidate . name ,
" phone " : candidate . mobile ,
" address " : candidate . address ,
" dob " : candidate . dob ,
}
2024-06-19 12:07:25 +05:30
session_key = request . session . session_key
user = portal_user [ session_key ]
2024-06-28 16:37:58 +05:30
if Employee . objects . filter ( email = user ) . exists ( ) :
messages . success ( request , _ ( " Employee with email id already exists. " ) )
return redirect ( " login " )
2023-08-21 17:28:32 +05:30
if Employee . objects . filter ( employee_user_id = user ) . first ( ) is not None :
2024-06-19 12:07:25 +05:30
employee = Employee . objects . filter ( employee_user_id = user ) . first ( )
if employee . employee_bank_details :
messages . success ( request , _ ( " Employee already exists.. " ) )
return redirect ( " login " )
2023-09-11 15:37:32 +05:30
initial = Employee . objects . filter ( employee_user_id = user ) . first ( ) . __dict__
2023-08-21 17:28:32 +05:30
2023-06-06 12:27:41 +05:30
form = EmployeeCreationForm (
2024-06-19 12:07:25 +05:30
initial = initial ,
2023-06-06 12:27:41 +05:30
)
2024-06-19 12:07:25 +05:30
# form.errors.clear()
2023-08-21 17:28:32 +05:30
if request . method == " POST " :
instance = Employee . objects . filter ( employee_user_id = user ) . first ( )
2024-06-19 12:07:25 +05:30
form = EmployeeCreationForm (
2023-08-21 17:28:32 +05:30
request . POST ,
instance = instance ,
2023-06-06 12:27:41 +05:30
)
2024-06-19 12:07:25 +05:30
if form . is_valid ( ) :
user . save ( )
login ( request , user )
employee_personal_info = form . save ( commit = False )
2023-08-21 17:28:32 +05:30
employee_personal_info . employee_user_id = user
employee_personal_info . email = candidate . email
2025-08-29 12:00:36 +05:30
if candidate . profile : # 896
filename = os . path . basename ( candidate . profile . name )
employee_personal_info . employee_profile . save (
filename , ContentFile ( candidate . profile . read ( ) ) , save = False
)
2024-09-24 16:44:33 +05:30
employee_personal_info . is_from_onboarding = True
2023-08-21 17:28:32 +05:30
employee_personal_info . save ( )
2025-08-29 12:00:36 +05:30
EmployeeWorkInformation . objects . update_or_create (
2023-08-21 17:28:32 +05:30
employee_id = employee_personal_info ,
2025-08-29 12:00:36 +05:30
defaults = {
" department_id " : candidate . job_position_id . department_id ,
" job_position_id " : candidate . job_position_id ,
" company_id " : candidate . recruitment_id . company_id ,
" date_joining " : candidate . joining_date ,
" email " : candidate . email ,
} ,
2023-08-21 17:28:32 +05:30
)
2025-08-29 12:00:36 +05:30
Document . objects . bulk_create (
[
Document (
title = doc . title ,
employee_id = employee_personal_info ,
document = doc . document ,
status = doc . status ,
reject_reason = doc . reject_reason ,
)
for doc in candidate . candidatedocument_set . all ( )
]
)
2023-09-11 15:37:32 +05:30
onboarding_portal . count = 3
2023-08-21 17:28:32 +05:30
onboarding_portal . save ( )
messages . success (
request , _ ( " Employee personal details created successfully.. " )
)
return redirect ( " employee-bank-details " , token )
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/employee_creation.html " ,
2023-08-21 17:28:32 +05:30
{ " form " : form , " employee " : candidate . recruitment_id . company_id } ,
)
2023-05-10 15:06:57 +05:30
def employee_bank_details ( request , token ) :
"""
function used to create employee bank details creation .
Parameters :
request ( HttpRequest ) : The HTTP request object .
token : random generated onboarding portal token
Returns :
GET : return bank details creation template
POST : return employee_bank_details_save function
"""
onboarding_portal = OnboardingPortal . objects . get ( token = token )
2023-08-21 17:28:32 +05:30
user = User . objects . filter ( username = onboarding_portal . candidate_id . email ) . first ( )
2023-09-11 15:37:32 +05:30
employee = Employee . objects . filter ( employee_user_id = user ) . first ( )
2024-06-19 12:07:25 +05:30
bank_info = EmployeeBankDetails . objects . filter ( employee_id = employee ) . first ( )
form = BankDetailsCreationForm ( instance = bank_info )
2023-08-21 17:28:32 +05:30
if request . method == " POST " :
2023-09-11 15:37:32 +05:30
form = BankDetailsCreationForm (
request . POST ,
2024-06-19 12:07:25 +05:30
instance = bank_info ,
2023-09-11 15:37:32 +05:30
)
2023-08-21 17:28:32 +05:30
if form . is_valid ( ) :
return employee_bank_details_save ( form , request , onboarding_portal )
return redirect ( welcome_aboard )
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/employee_bank_details.html " ,
2023-08-21 17:28:32 +05:30
{
" form " : form ,
" company " : onboarding_portal . candidate_id . recruitment_id . company_id ,
} ,
)
2023-05-10 15:06:57 +05:30
def employee_bank_details_save ( form , request , onboarding_portal ) :
"""
function used to save employee bank details .
Parameters :
request ( HttpRequest ) : The HTTP request object .
form : Form object .
onboarding_portal : Onboarding portal object .
Returns :
GET : return welcome onboard view
"""
employee_bank_detail = form . save ( commit = False )
2024-06-19 12:07:25 +05:30
employee = Employee . objects . get ( employee_user_id = request . user )
employee_bank_detail . employee_id = employee
candidate = onboarding_portal . candidate_id
candidate . converted_employee_id = employee
candidate . save ( )
2023-05-10 15:06:57 +05:30
employee_bank_detail . save ( )
2023-08-21 17:28:32 +05:30
onboarding_portal . count = 4
2024-06-19 12:07:25 +05:30
onboarding_portal . used = True
2023-05-10 15:06:57 +05:30
onboarding_portal . save ( )
2023-06-06 12:27:41 +05:30
messages . success ( request , _ ( " Employee bank details created successfully.. " ) )
2023-05-10 15:06:57 +05:30
return redirect ( welcome_aboard )
@login_required
def welcome_aboard ( request ) :
"""
function used to view welcome aboard .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
GET : return welcome onboard view
"""
2023-09-27 13:55:34 +05:30
return render ( request , " onboarding/welcome_aboard.html " )
2023-05-10 15:06:57 +05:30
@login_required
2023-06-06 12:27:41 +05:30
@require_http_methods ( [ " POST " ] )
@all_manager_can_enter ( " onboarding.change_candidatetask " )
2024-01-20 12:51:17 +05:30
def candidate_task_update ( request , taskId ) :
2023-05-10 15:06:57 +05:30
"""
function used to update candidate task .
Parameters :
request ( HttpRequest ) : The HTTP request object .
2023-06-06 12:27:41 +05:30
obj_id : candidate task id
2023-05-10 15:06:57 +05:30
Returns :
POST : return candidate task template
"""
2024-01-20 12:51:17 +05:30
status = request . POST . get ( " status " )
if request . POST . get ( " single_view " ) :
candidate_task = CandidateTask . objects . get ( id = taskId )
else :
canId = request . POST . get ( " candId " )
onboarding_task = OnboardingTask . objects . get ( id = taskId )
2024-01-23 15:29:05 +05:30
candidate = Candidate . objects . get ( id = canId )
candidate_task = CandidateTask . objects . filter (
candidate_id = candidate , onboarding_task_id = onboarding_task
) . first ( )
2023-06-06 12:27:41 +05:30
candidate_task . status = status
candidate_task . save ( )
users = [
employee . employee_user_id
for employee in candidate_task . onboarding_task_id . employee_id . all ( )
]
notify . send (
request . user . employee_get ,
recipient = users ,
verb = f " The task { candidate_task . onboarding_task_id } of \
{ candidate_task . candidate_id } was updated to { candidate_task . status } . " ,
2023-07-26 12:15:01 +05:30
verb_ar = f " تم تحديث المهمة { candidate_task . onboarding_task_id } للمرشح { candidate_task . candidate_id } إلى { candidate_task . status } . " ,
verb_de = f " Die Aufgabe { candidate_task . onboarding_task_id } des Kandidaten { candidate_task . candidate_id } wurde auf { candidate_task . status } aktualisiert. " ,
verb_es = f " La tarea { candidate_task . onboarding_task_id } del candidato { candidate_task . candidate_id } se ha actualizado a { candidate_task . status } . " ,
verb_fr = f " La tâche { candidate_task . onboarding_task_id } du candidat { candidate_task . candidate_id } a été mise à jour à { candidate_task . status } . " ,
2023-06-06 12:27:41 +05:30
icon = " people-circle " ,
2024-06-28 16:37:58 +05:30
redirect = reverse ( " onboarding-view " ) ,
2023-06-06 12:27:41 +05:30
)
2024-01-20 12:51:17 +05:30
return JsonResponse (
2024-02-16 16:44:35 +05:30
{ " message " : _ ( " Candidate onboarding task updated " ) , " type " : " success " }
2024-01-20 12:51:17 +05:30
)
2024-01-23 15:29:05 +05:30
2024-01-20 12:51:17 +05:30
@login_required
2024-01-23 15:29:05 +05:30
def get_status ( request , task_id ) :
2024-01-20 12:51:17 +05:30
"""
htmx function that return the status of candidate task
Parameters :
request ( HttpRequest ) : The HTTP request object .
task_id : Onboarding task id
Returns :
POST : return candidate task template
"""
2024-01-23 15:29:05 +05:30
cand_id = request . GET . get ( " cand_id " )
cand_stage = request . GET . get ( " cand_stage " )
cand_stage_obj = CandidateStage . objects . get ( id = cand_stage )
2024-01-20 12:51:17 +05:30
onboarding_task = OnboardingTask . objects . get ( id = task_id )
2024-01-23 15:29:05 +05:30
candidate = Candidate . objects . get ( id = cand_id )
candidate_task = CandidateTask . objects . filter (
candidate_id = candidate , onboarding_task_id = onboarding_task
) . first ( )
2024-01-20 12:51:17 +05:30
status = candidate_task . status
2024-01-23 15:29:05 +05:30
return render (
request ,
" onboarding/candidate_task.html " ,
{
" status " : status ,
" task " : onboarding_task ,
" candidate " : cand_stage_obj ,
" second_load " : True ,
" choices " : CandidateTask . choice ,
} ,
)
2024-01-20 12:51:17 +05:30
@login_required
@all_manager_can_enter ( " onboarding.change_candidatetask " )
2024-01-23 15:29:05 +05:30
def assign_task ( request , task_id ) :
2024-01-20 12:51:17 +05:30
"""
2024-01-23 15:29:05 +05:30
htmx function that used to assign a onboarding task to candidate
2024-01-20 12:51:17 +05:30
Parameters :
request ( HttpRequest ) : The HTTP request object .
task_id : Onboarding task id
Returns :
POST : return candidate task template
"""
2024-01-23 15:29:05 +05:30
stage_id = request . GET . get ( " stage_id " )
cand_id = request . GET . get ( " cand_id " )
cand_stage = request . GET . get ( " cand_stage " )
cand_stage_obj = CandidateStage . objects . get ( id = cand_stage )
onboarding_task = OnboardingTask . objects . get ( id = task_id )
candidate = Candidate . objects . get ( id = cand_id )
2024-01-20 12:51:17 +05:30
onboarding_stage = OnboardingStage . objects . get ( id = stage_id )
2024-01-23 15:29:05 +05:30
cand_task , created = CandidateTask . objects . get_or_create (
2024-01-20 12:51:17 +05:30
candidate_id = candidate ,
2024-01-23 15:29:05 +05:30
stage_id = onboarding_stage ,
onboarding_task_id = onboarding_task ,
2023-06-06 12:27:41 +05:30
)
2024-01-20 12:51:17 +05:30
cand_task . save ( )
onboarding_task . candidates . add ( candidate )
2024-01-23 15:29:05 +05:30
return render (
request ,
" onboarding/candidate_task.html " ,
{
" status " : cand_task . status ,
" task " : onboarding_task ,
" candidate " : cand_stage_obj ,
" second_load " : True ,
" choices " : CandidateTask . choice ,
} ,
)
2023-05-10 15:06:57 +05:30
@login_required
2023-06-06 12:27:41 +05:30
@require_http_methods ( [ " POST " ] )
@stage_manager_can_enter ( " onboarding.change_candidatestage " )
2023-05-10 15:06:57 +05:30
def candidate_stage_update ( request , candidate_id , recruitment_id ) :
"""
function used to update candidate stage .
Parameters :
request ( HttpRequest ) : The HTTP request object .
candidate_id : Candidate id
recruitment_id : Recruitment id
Returns :
POST : return candidate task template
"""
2023-06-06 12:27:41 +05:30
stage_id = request . POST . get ( " stage " )
2024-02-15 12:12:23 +05:30
recruitments = Recruitment . objects . filter ( id = recruitment_id )
2023-06-06 12:27:41 +05:30
stage = OnboardingStage . objects . get ( id = stage_id )
candidate = Candidate . objects . get ( id = candidate_id )
candidate_stage = CandidateStage . objects . get ( candidate_id = candidate )
candidate_stage . onboarding_stage_id = stage
candidate_stage . save ( )
onboarding_stages = OnboardingStage . objects . all ( )
2023-08-31 16:45:36 +05:30
choices = CandidateTask . choice
2023-06-06 12:27:41 +05:30
users = [
employee . employee_user_id
for employee in candidate_stage . onboarding_stage_id . employee_id . all ( )
]
2023-08-31 16:45:36 +05:30
if request . POST . get ( " is_ajax " ) is None :
notify . send (
request . user . employee_get ,
recipient = users ,
verb = f " The stage of { candidate_stage . candidate_id } \
was updated to { candidate_stage . onboarding_stage_id } . " ,
verb_ar = f " تم تحديث مرحلة المرشح { candidate_stage . candidate_id } إلى { candidate_stage . onboarding_stage_id } . " ,
verb_de = f " Die Phase des Kandidaten { candidate_stage . candidate_id } wurde auf { candidate_stage . onboarding_stage_id } aktualisiert. " ,
verb_es = f " La etapa del candidato { candidate_stage . candidate_id } se ha actualizado a { candidate_stage . onboarding_stage_id } . " ,
verb_fr = f " L ' étape du candidat { candidate_stage . candidate_id } a été mise à jour à { candidate_stage . onboarding_stage_id } . " ,
icon = " people-circle " ,
2024-06-28 16:37:58 +05:30
redirect = reverse ( " onboarding-view " ) ,
2023-08-31 16:45:36 +05:30
)
2024-02-28 15:31:01 +05:30
groups = onboarding_query_grouper ( request , recruitments )
for item in groups :
setattr ( item [ " recruitment " ] , " stages " , item [ " stages " ] )
2023-08-31 16:45:36 +05:30
return render (
request ,
2023-09-27 13:55:34 +05:30
" onboarding/onboarding_table.html " ,
2023-08-31 16:45:36 +05:30
{
2024-02-15 12:12:23 +05:30
" recruitment " : groups [ 0 ] [ " recruitment " ] ,
2023-08-31 16:45:36 +05:30
" onboarding_stages " : onboarding_stages ,
" choices " : choices ,
} ,
)
2023-09-11 15:37:32 +05:30
return JsonResponse (
2023-09-12 11:59:58 +05:30
{ " message " : _ ( " Candidate onboarding stage updated " ) , " type " : " success " }
2023-09-11 15:37:32 +05:30
)
2023-05-10 15:06:57 +05:30
2023-10-20 14:48:55 +05:30
@login_required
@require_http_methods ( [ " POST " ] )
@stage_manager_can_enter ( " onboarding.change_candidatestage " )
def candidate_stage_bulk_update ( request ) :
candiate_ids = request . POST [ " ids " ]
recrutment_id = request . POST [ " recruitment " ]
candidate_id_list = json . loads ( candiate_ids )
stage = request . POST [ " stage " ]
onboarding_stages = OnboardingStage . objects . all ( )
2024-02-16 16:44:35 +05:30
recruitments = Recruitment . objects . filter ( id = int ( recrutment_id ) )
2023-10-20 14:48:55 +05:30
choices = CandidateTask . choice
2024-02-20 17:05:43 +05:30
CandidateStage . objects . filter ( candidate_id__id__in = candidate_id_list ) . update (
onboarding_stage_id = stage
)
2024-02-16 16:44:35 +05:30
type = " info "
message = " No candidates selected "
if candidate_id_list :
type = " success "
message = " Candidate stage updated successfully "
2024-02-28 15:31:01 +05:30
groups = onboarding_query_grouper ( request , recruitments )
for item in groups :
setattr ( item [ " recruitment " ] , " stages " , item [ " stages " ] )
2023-10-20 14:48:55 +05:30
response = render (
request ,
" onboarding/onboarding_table.html " ,
{
2024-02-16 16:44:35 +05:30
" recruitment " : groups [ 0 ] [ " recruitment " ] ,
2023-10-20 14:48:55 +05:30
" onboarding_stages " : onboarding_stages ,
" choices " : choices ,
} ,
)
return HttpResponse (
2023-11-08 16:12:02 +05:30
response . content . decode ( " utf-8 " )
2024-02-16 16:44:35 +05:30
+ f ' <div><div class= " oh-alert-container " ><div class= " oh-alert oh-alert--animated oh-alert-- { type } " > { message } </div> </div></div> '
2023-10-20 14:48:55 +05:30
)
@login_required
@require_http_methods ( [ " POST " ] )
@all_manager_can_enter ( " onboarding.change_candidatetask " )
def candidate_task_bulk_update ( request ) :
candiate_ids = request . POST [ " ids " ]
candidate_id_list = json . loads ( candiate_ids )
task = request . POST [ " task " ]
status = request . POST [ " status " ]
2023-11-08 16:12:02 +05:30
count = CandidateTask . objects . filter (
candidate_id__id__in = candidate_id_list , onboarding_task_id = task
) . update ( status = status )
2023-10-20 14:48:55 +05:30
# messages.success(request,f"{count} candidate's task status updated successfully")
return JsonResponse (
{ " message " : _ ( " Candidate onboarding stage updated " ) , " type " : " success " }
)
2023-05-10 15:06:57 +05:30
@login_required
2023-10-24 19:17:43 +05:30
def onboard_candidate_chart ( request ) :
2023-05-10 15:06:57 +05:30
"""
function used to show onboard started candidates in recruitments .
Parameters :
request ( HttpRequest ) : The HTTP request object .
Returns :
GET : return Json response labels , data , background_color , border_color .
"""
labels = [ ]
data = [ ]
background_color = [ ]
border_color = [ ]
2024-02-17 14:43:31 +05:30
recruitments = Recruitment . objects . filter ( closed = False , is_active = True )
2023-05-10 15:06:57 +05:30
for recruitment in recruitments :
2023-06-06 12:27:41 +05:30
red = random . randint ( 0 , 255 )
green = random . randint ( 0 , 255 )
blue = random . randint ( 0 , 255 )
background_color . append ( f " rgba( { red } , { green } , { blue } , 0.2 " )
border_color . append ( f " rgb( { red } , { green } , { blue } ) " )
2023-09-01 11:39:05 +05:30
labels . append ( recruitment . title )
2024-02-20 17:05:43 +05:30
data . append ( recruitment . candidate . filter ( start_onboard = True ) . count ( ) )
2023-06-06 12:27:41 +05:30
return JsonResponse (
{
" labels " : labels ,
" data " : data ,
" background_color " : background_color ,
" border_color " : border_color ,
2024-11-24 10:46:32 +05:30
" message " : _ ( " No records available at the moment. " ) ,
2023-06-06 12:27:41 +05:30
} ,
safe = False ,
)
@login_required
2025-04-23 22:54:57 +05:30
@permission_required ( " candidate.change_candidate " )
@csrf_exempt
@require_POST
2023-06-06 12:27:41 +05:30
def update_joining ( request ) :
"""
2025-04-23 22:54:57 +05:30
Ajax method to update joining date of candidate
2023-06-06 12:27:41 +05:30
"""
2025-04-23 22:54:57 +05:30
cand_id = request . POST . get ( " candId " )
date_value = request . POST . get ( " date " )
if not cand_id :
messages . error ( request , _ ( " Missing candidate ID. " ) )
return JsonResponse ( { " type " : " danger " } , status = 400 )
if date_value is None :
messages . error ( request , _ ( " Missing date of joining. " ) )
return JsonResponse ( { " type " : " danger " } , status = 400 )
if date_value == " " :
date_value = None
candidate_obj = Candidate . find ( cand_id )
if not candidate_obj :
messages . error ( request , _ ( " Candidate not found " ) )
return JsonResponse ( { " type " : " danger " } , status = 400 )
candidate_obj . joining_date = date_value
2023-06-06 12:27:41 +05:30
candidate_obj . save ( )
2025-04-23 22:54:57 +05:30
messages . success (
request ,
_ ( " {candidate} ' s Date of joining updated successfully " ) . format (
candidate = candidate_obj . name
) ,
2023-09-11 15:37:32 +05:30
)
2025-04-23 22:54:57 +05:30
return JsonResponse ( { " type " : " success " } )
2023-08-31 16:45:36 +05:30
@login_required
2025-05-22 16:15:25 +05:30
@permission_required ( perm = " recruitment.view_candidate " )
2023-08-31 16:45:36 +05:30
def view_dashboard ( request ) :
2023-09-11 15:37:32 +05:30
recruitment = Recruitment . objects . all ( ) . values_list ( " title " , flat = True )
2023-08-31 16:45:36 +05:30
candidates = Candidate . objects . all ( )
2023-09-04 09:57:12 +05:30
hired = candidates . filter ( start_onboard = True )
2023-09-11 15:37:32 +05:30
onboard_candidates = Candidate . objects . filter ( start_onboard = True )
job_positions = onboard_candidates . values_list (
" job_position_id__job_position " , flat = True
)
2023-08-31 16:45:36 +05:30
context = {
2023-09-11 15:37:32 +05:30
" recruitment " : list ( recruitment ) ,
" candidates " : candidates ,
" hired " : hired ,
" onboard_candidates " : onboard_candidates ,
" job_positions " : list ( set ( job_positions ) ) ,
2023-08-31 16:45:36 +05:30
}
2023-09-11 15:37:32 +05:30
return render ( request , " onboarding/dashboard.html " , context = context )
2023-08-31 16:45:36 +05:30
@login_required
2025-05-22 16:15:25 +05:30
@permission_required ( perm = " recruitment.view_candidate " )
2023-08-31 16:45:36 +05:30
def dashboard_stage_chart ( request ) :
recruitment = request . GET . get ( " recruitment " )
2023-09-11 15:37:32 +05:30
labels = OnboardingStage . objects . filter (
recruitment_id__title = recruitment
) . values_list ( " stage_title " , flat = True )
2023-08-31 16:45:36 +05:30
labels = list ( labels )
candidate_counts = [ ]
border_color = [ ]
2023-09-11 15:37:32 +05:30
background_color = [ ]
2023-08-31 16:45:36 +05:30
for label in labels :
red = random . randint ( 0 , 255 )
green = random . randint ( 0 , 255 )
blue = random . randint ( 0 , 255 )
background_color . append ( f " rgba( { red } , { green } , { blue } , 0.3 " )
border_color . append ( f " rgb( { red } , { green } , { blue } ) " )
2023-09-11 15:37:32 +05:30
count = CandidateStage . objects . filter (
onboarding_stage_id__stage_title = label ,
onboarding_stage_id__recruitment_id__title = recruitment ,
) . count ( )
2023-08-31 16:45:36 +05:30
candidate_counts . append ( count )
response = {
2023-09-11 15:37:32 +05:30
" labels " : labels ,
" data " : candidate_counts ,
" recruitment " : recruitment ,
" background_color " : background_color ,
" border_color " : border_color ,
2023-09-27 13:55:34 +05:30
" message " : _ ( " No candidates started onboarding.... " ) ,
2023-08-31 16:45:36 +05:30
}
return JsonResponse ( response )
@login_required
@stage_manager_can_enter ( " recruitment.change_candidate " )
def candidate_sequence_update ( request ) :
"""
This method is used to update the sequence of candidate
"""
sequence_data = json . loads ( request . POST [ " sequenceData " ] )
updated = False
for cand_id , seq in sequence_data . items ( ) :
cand = CandidateStage . objects . get ( id = cand_id )
if cand . sequence != seq :
cand . sequence = seq
cand . save ( )
updated = True
if updated :
2023-09-15 11:13:26 +05:30
return JsonResponse (
{ " message " : _ ( " Candidate sequence updated " ) , " type " : " info " }
)
2023-08-31 16:45:36 +05:30
return JsonResponse ( { " type " : " fail " } )
@login_required
@stage_manager_can_enter ( " recruitment.change_stage " )
def stage_sequence_update ( request ) :
"""
This method is used to update the sequence of the stages
"""
sequence_data = json . loads ( request . POST [ " sequenceData " ] )
updated = False
for stage_id , seq in sequence_data . items ( ) :
stage = OnboardingStage . objects . get ( id = stage_id )
if stage . sequence != seq :
stage . sequence = seq
stage . save ( )
updated = True
2023-09-11 15:37:32 +05:30
2023-08-31 16:45:36 +05:30
if updated :
2023-09-15 11:13:26 +05:30
return JsonResponse ( { " type " : " success " , " message " : _ ( " Stage sequence updated " ) } )
2023-08-31 16:45:36 +05:30
return JsonResponse ( { " type " : " fail " } )
2023-09-15 11:13:26 +05:30
@login_required
@require_http_methods ( [ " POST " ] )
@hx_request_required
def stage_name_update ( request , stage_id ) :
"""
This method is used to update the name of recruitment stage
"""
stage_obj = OnboardingStage . objects . get ( id = stage_id )
stage_obj . stage_title = request . POST [ " stage " ]
stage_obj . save ( )
message = _ ( " The stage title has been updated successfully " )
return HttpResponse (
f ' <div class= " oh-alert-container " ><div class= " oh-alert oh-alert--animated oh-alert--success " > { message } </div></div> '
)
2023-08-31 16:45:36 +05:30
@login_required
2024-05-30 10:07:39 +05:30
@hx_request_required
2023-08-31 16:45:36 +05:30
@stage_manager_can_enter ( " recruitment.change_candidate " )
2023-09-11 15:37:32 +05:30
def onboarding_send_mail ( request , candidate_id ) :
2023-08-31 16:45:36 +05:30
"""
This method is used to send mail to the candidate from onboarding view
"""
candidate = Candidate . objects . get ( id = candidate_id )
candidate_mail = candidate . email
2023-09-11 15:37:32 +05:30
response = render (
2023-09-27 13:55:34 +05:30
request , " onboarding/send_mail_form.html " , { " candidate " : candidate }
2023-09-11 15:37:32 +05:30
)
2024-03-07 11:57:28 +05:30
email_backend = ConfiguredEmailBackend ( )
2024-09-20 15:39:16 +05:30
display_email_name = email_backend . dynamic_from_email_with_display_name
if request :
try :
display_email_name = f " { request . user . employee_get . get_full_name ( ) } < { request . user . employee_get . email } > "
except :
logger . error ( Exception )
2023-08-31 16:45:36 +05:30
if request . method == " POST " :
2023-09-11 15:37:32 +05:30
subject = request . POST [ " subject " ]
2023-08-31 16:45:36 +05:30
body = request . POST [ " body " ]
with contextlib . suppress ( Exception ) :
res = send_mail (
2023-09-11 15:37:32 +05:30
subject ,
body ,
2024-09-20 15:39:16 +05:30
display_email_name ,
2023-09-11 15:37:32 +05:30
[ candidate_mail ] ,
fail_silently = False ,
2023-08-31 16:45:36 +05:30
)
if res == 1 :
2023-09-11 15:37:32 +05:30
messages . success ( request , _ ( " Mail sent successfully " ) )
2023-08-31 16:45:36 +05:30
else :
2023-09-11 15:37:32 +05:30
messages . error ( request , _ ( " Something went wrong " ) )
2023-08-31 16:45:36 +05:30
return HttpResponse (
response . content . decode ( " utf-8 " ) + " <script>location.reload();</script> "
)
return response
2024-01-23 15:29:05 +05:30
@login_required
@stage_manager_can_enter ( " recruitment.change_stage " )
2025-04-23 22:54:57 +05:30
@csrf_exempt
@require_POST
2024-01-23 15:29:05 +05:30
def update_probation_end ( request ) :
"""
2025-04-23 22:54:57 +05:30
Updates the probation end date for a candidate .
2024-01-23 15:29:05 +05:30
"""
2025-04-23 22:54:57 +05:30
candidate_id = request . POST . get ( " candidate_id " )
probation_end = request . POST . get ( " probation_end " )
if not candidate_id :
messages . error ( request , _ ( " Missing candidate ID. " ) )
return JsonResponse ( { " type " : " danger " } , status = 400 )
try :
candidate = Candidate . objects . get ( id = candidate_id )
except Candidate . DoesNotExist :
messages . error ( request , _ ( " Candidate not found. " ) )
return JsonResponse ( { " type " : " danger " } , status = 404 )
if probation_end == " " :
probation_end = None
candidate . probation_end = probation_end
candidate . save ( )
messages . success ( request , _ ( " Probation end date updated " ) )
return JsonResponse ( { " type " : " success " } )
2024-02-05 13:53:16 +05:30
@login_required
2024-05-30 10:07:39 +05:30
@hx_request_required
2024-02-05 13:53:16 +05:30
@all_manager_can_enter ( " onboarding.change_onboardingtask " )
def task_report ( request ) :
"""
This method is used to show the task report .
"""
employee_id = request . GET . get ( " employee_id " )
if not employee_id :
employee_id = request . user . employee_get . id
my_tasks = OnboardingTask . objects . filter (
employee_id__id = employee_id ,
2024-02-20 17:05:43 +05:30
candidates__is_active = True ,
2024-02-05 13:53:16 +05:30
candidates__recruitment_id__closed = False ,
) . distinct ( )
tasks = [ ]
for task in my_tasks :
tasks . append (
{
" task " : task ,
" total_candidates " : task . candidatetask_set . count ( ) ,
" todo " : task . candidatetask_set . filter ( status = " todo " ) . count ( ) ,
" scheduled " : task . candidatetask_set . filter ( status = " scheduled " ) . count ( ) ,
" ongoing " : task . candidatetask_set . filter ( status = " ongoing " ) . count ( ) ,
" stuck " : task . candidatetask_set . filter ( status = " stuck " ) . count ( ) ,
" done " : task . candidatetask_set . filter ( status = " done " ) . count ( ) ,
}
)
return render ( request , " onboarding/dashboard/task_report.html " , { " tasks " : tasks } )
@login_required
@all_manager_can_enter ( " onboarding.view_candidatetask " )
def candidate_tasks_status ( request ) :
"""
This method is used to render template to show the onboarding tasks
"""
task_id = request . GET [ " task_id " ]
candidate_tasks = CandidateTask . objects . filter ( onboarding_task_id__id = task_id )
return render (
request ,
" onboarding/dashboard/status_list.html " ,
{ " candidate_tasks " : candidate_tasks } ,
)
@login_required
@all_manager_can_enter ( " onboarding.change_candidatetask " )
def change_task_status ( request ) :
"""
This method is to update the candidate task
"""
task_id = request . GET [ " task_id " ]
candidate_task = CandidateTask . objects . get ( id = task_id )
status = request . GET [ " status " ]
if status in [
" todo " ,
" scheduled " ,
" ongoing " ,
" stuck " ,
" done " ,
] :
candidate_task . status = status
candidate_task . save ( )
return HttpResponse ( " Success " )
2024-02-06 13:01:09 +05:30
@login_required
@permission_required ( " recruitment.change_recruitment " )
def update_offer_letter_status ( request ) :
"""
This method is used to update the offer letter status
"""
2025-04-22 04:18:35 -04:00
candidate_id = request . GET . get ( " candidate_id " )
status = request . GET . get ( " status " )
candidate = None
if not candidate_id or not status :
2025-04-23 22:54:57 +05:30
messages . error ( request , " candidate or status is missing " )
2025-04-22 04:18:35 -04:00
return redirect ( " /onboarding/candidates-view/ " )
if not status in [ " not_sent " , " sent " , " accepted " , " rejected " , " joined " ] :
2025-04-23 22:54:57 +05:30
messages . error ( request , " Please Pass valid status " )
2025-04-22 04:18:35 -04:00
return redirect ( " /onboarding/candidates-view/ " )
try :
candidate = Candidate . objects . get ( id = candidate_id )
except Candidate . DoesNotExist :
2025-04-23 22:54:57 +05:30
messages . error ( request , " Candidate not found " )
2025-04-22 04:18:35 -04:00
return redirect ( " /onboarding/candidates-view/ " )
2024-02-06 13:01:09 +05:30
if status in [ " not_sent " , " sent " , " accepted " , " rejected " , " joined " ] :
candidate . offer_letter_status = status
candidate . save ( )
2025-04-23 22:54:57 +05:30
messages . success ( request , " Status of offer letter updated successfully " )
url = " /onboarding/candidates-view/ "
2025-04-22 04:18:35 -04:00
return HttpResponse (
2025-04-23 22:54:57 +05:30
f """
2025-04-22 04:18:35 -04:00
< script >
window . location . href = " {url} "
< / script >
"""
2025-04-23 22:54:57 +05:30
)
2024-02-06 13:01:09 +05:30
@login_required
2024-05-30 10:07:39 +05:30
@hx_request_required
2024-02-06 13:01:09 +05:30
@permission_required ( " recruitment.add_rejectedcandidate " )
def add_to_rejected_candidates ( request ) :
"""
This method is used to add candidates to rejected candidates
"""
candidate_id = request . GET . get ( " candidate_id " )
instance = None
if candidate_id :
instance = RejectedCandidate . objects . filter ( candidate_id = candidate_id ) . first ( )
2024-02-20 17:05:43 +05:30
form = RejectedCandidateForm (
initial = { " candidate_id " : candidate_id } , instance = instance
)
2024-02-06 13:01:09 +05:30
if request . method == " POST " :
2024-02-20 17:05:43 +05:30
form = RejectedCandidateForm ( request . POST , instance = instance )
2024-02-06 13:01:09 +05:30
if form . is_valid ( ) :
form . save ( )
2024-03-27 14:20:20 +05:30
form = RejectedCandidateForm ( )
2024-02-20 17:05:43 +05:30
messages . success ( request , " Candidate reject reason saved " )
2024-02-06 13:01:09 +05:30
return HttpResponse ( " <script>window.location.reload()</script> " )
return render ( request , " onboarding/rejection/form.html " , { " form " : form } )
2024-02-22 22:57:56 +05:30
2025-10-20 15:22:49 +05:30
@login_required
@hx_request_required
@permission_required ( " recruitment.delete_rejectedcandidate " )
def delete_candidate_rejection ( request , rej_id ) :
"""
This method is used to delete candidate rejection
"""
try :
instance = RejectedCandidate . objects . filter ( id = rej_id ) . first ( )
if instance :
instance . delete ( )
messages . success ( request , " Candidate rejection deleted successfully " )
else :
messages . error ( request , " Candidate rejection not found " )
except Exception as e :
messages . error ( request , " Error occurred while deleting candidate rejection " )
return HttpResponse ( " <script>window.location.reload()</script> " )
2024-02-22 22:57:56 +05:30
@login_required
def candidate_select ( request ) :
"""
This method is used for select all in candidate
"""
page_number = request . GET . get ( " page " )
2024-03-07 11:57:28 +05:30
employees = queryset = Candidate . objects . filter (
hired = True ,
recruitment_id__closed = False ,
is_active = True ,
)
2024-02-22 22:57:56 +05:30
employee_ids = [ str ( emp . id ) for emp in employees ]
total_count = employees . count ( )
context = { " employee_ids " : employee_ids , " total_count " : total_count }
return JsonResponse ( context , safe = False )
@login_required
@permission_required ( " recruitment.view_candidate " )
def candidate_select_filter ( request ) :
"""
This method is used to select all filtered candidates
"""
page_number = request . GET . get ( " page " )
filtered = request . GET . get ( " filter " )
filters = json . loads ( filtered ) if filtered else { }
if page_number == " all " :
candidate_filter = CandidateFilter (
filters ,
queryset = Candidate . objects . filter (
hired = True ,
recruitment_id__closed = False ,
is_active = True ,
) ,
)
# Get the filtered queryset
filtered_candidates = candidate_filter . qs
employee_ids = [ str ( emp . id ) for emp in filtered_candidates ]
total_count = filtered_candidates . count ( )
context = { " employee_ids " : employee_ids , " total_count " : total_count }
return JsonResponse ( context )
2024-09-03 17:16:25 +05:30
def offer_letter_bulk_status_update ( request ) :
"""
This function is used to bulk update the offerletter status
"""
ids = json . loads ( request . GET . get ( " ids " , [ ] ) )
status = request . GET . get ( " status " )
for id in ids :
try :
candidate = Candidate . objects . filter ( id = int ( id ) ) . first ( )
if candidate . offer_letter_status != status :
candidate . offer_letter_status = status
candidate . save ( )
messages . success ( request , " offer letter status updated successfully " )
else :
messages . error ( request , " Status already in {} status " . format ( status ) )
except :
messages . error ( request , " Candidate doesnot exist " )
return JsonResponse ( " success " , safe = False )
def onboarding_candidate_bulk_delete ( request ) :
"""
This function is used to bulk delete onboarding candidates
"""
ids = json . loads ( request . GET . get ( " ids " , [ ] ) )
status = request . GET . get ( " status " )
for id in ids :
try :
candidate = Candidate . objects . filter ( id = int ( id ) ) . first ( )
candidate . delete ( )
messages . success ( request , " candidate deleted successfully " )
except :
messages . error ( request , " Candidate doesnot exist " )
return JsonResponse ( " success " , safe = False )