From a614facf0a74464631af1ec020b83fdea5c9cf5e Mon Sep 17 00:00:00 2001 From: Horilla Date: Wed, 28 Aug 2024 12:00:34 +0530 Subject: [PATCH] [UPDT] RECRUITMENT: Optional profile/resume option under recruitment --- recruitment/forms.py | 54 +++++++++++++++---- recruitment/models.py | 6 +++ recruitment/scheduler.py | 8 +-- .../templates/candidate/application_form.html | 2 +- .../components/candidate_stage_component.html | 6 ++- .../pipeline/form/recruitment_update.html | 20 ++++++- .../recruitment/recruitment_form.html | 24 ++++++++- .../recruitment/recruitment_update_form.html | 18 ++++++- recruitment/views/surveys.py | 14 ++--- 9 files changed, 124 insertions(+), 28 deletions(-) diff --git a/recruitment/forms.py b/recruitment/forms.py index c678094c1..9f9aad8f3 100644 --- a/recruitment/forms.py +++ b/recruitment/forms.py @@ -35,10 +35,10 @@ from django.utils.translation import gettext_lazy as _ from base.forms import Form from base.methods import reload_queryset -from base.models import HorillaMailTemplate from employee.filters import EmployeeFilter from employee.models import Employee from horilla import horilla_middlewares +from horilla.horilla_middlewares import _thread_locals from horilla_widgets.widgets.horilla_multi_select_field import HorillaMultiSelectField from horilla_widgets.widgets.select_widgets import HorillaMultiSelectWidget from recruitment import widgets @@ -352,11 +352,15 @@ class CandidateCreationForm(ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self.fields["profile"].widget.attrs["accept"] = ".jpg, .jpeg, .png" + self.fields["profile"].required = False + self.fields["resume"].widget.attrs["accept"] = ".pdf" + self.fields["resume"].required = False if self.instance.recruitment_id is not None: if self.instance is not None: self.fields["job_position_id"] = forms.ModelChoiceField( queryset=self.instance.recruitment_id.open_positions.all(), - # additional field options + label="Job Position", ) self.fields["recruitment_id"].widget.attrs = {"data-widget": "ajax-widget"} self.fields["job_position_id"].widget.attrs = {"data-widget": "ajax-widget"} @@ -429,26 +433,31 @@ class CandidateCreationForm(ModelForm): return table_html def clean(self): + errors = {} + profile = self.cleaned_data["profile"] + resume = self.cleaned_data["resume"] + recruitment: Recruitment = self.cleaned_data["recruitment_id"] + if not resume and not recruitment.optional_resume: + errors["resume"] = _("This field is required") + if not profile and not recruitment.optional_profile_image: + errors["profile"] = _("This field is required") if self.instance.name is not None: self.errors.pop("job_position_id", None) if ( self.instance.job_position_id is None or self.data.get("job_position_id") == "" ): - raise forms.ValidationError( - {"job_position_id": "This field is required"} - ) + errors["job_position_id"] = _("This field is required") if ( self.instance.job_position_id not in self.instance.recruitment_id.open_positions.all() ): - raise forms.ValidationError({"job_position_id": "Choose valid choice"}) + errors["job_position_id"] = _("Choose valid choice") + if errors: + raise ValidationError(errors) return super().clean() -from horilla.horilla_middlewares import _thread_locals - - class ApplicationForm(RegistrationForm): """ Form for create Candidate @@ -495,6 +504,10 @@ class ApplicationForm(RegistrationForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) request = getattr(_thread_locals, "request", None) + self.fields["profile"].widget.attrs["accept"] = ".jpg, .jpeg, .png" + self.fields["profile"].required = False + self.fields["resume"].widget.attrs["accept"] = ".pdf" + self.fields["resume"].required = False self.fields["recruitment_id"].widget.attrs = {"data-widget": "ajax-widget"} self.fields["job_position_id"].widget.attrs = {"data-widget": "ajax-widget"} @@ -505,10 +518,23 @@ class ApplicationForm(RegistrationForm): name = self.cleaned_data["name"] request = getattr(_thread_locals, "request", None) - if request and request.user.has_perm("recruitment.add_candidate"): + errors = {} + profile = self.cleaned_data["profile"] + resume = self.cleaned_data["resume"] + recruitment: Recruitment = self.cleaned_data["recruitment_id"] + if not resume and not recruitment.optional_resume: + errors["resume"] = _("This field is required") + if not profile and not recruitment.optional_profile_image: + errors["profile"] = _("This field is required") + if errors: + raise ValidationError(errors) + if ( + not profile + and request + and request.user.has_perm("recruitment.add_candidate") + ): profile_pic_url = f"https://ui-avatars.com/api/?name={name}" self.cleaned_data["profile"] = profile_pic_url - super().clean() return self.cleaned_data @@ -574,6 +600,12 @@ class AddCandidateForm(ModelForm): recruitment_id=recruitment ) self.fields["job_position_id"].queryset = recruitment.open_positions + self.fields["profile"].widget.attrs["accept"] = ".jpg, .jpeg, .png" + self.fields["resume"].widget.attrs["accept"] = ".pdf" + if recruitment.optional_profile_image: + self.fields["profile"].required = False + if recruitment.optional_resume: + self.fields["resume"].required = False self.fields["gender"].empty_label = None self.fields["job_position_id"].empty_label = None self.fields["stage_id"].empty_label = None diff --git a/recruitment/models.py b/recruitment/models.py index 67f6f088e..9cae6a5fd 100644 --- a/recruitment/models.py +++ b/recruitment/models.py @@ -158,6 +158,12 @@ class Recruitment(HorillaModel): skills = models.ManyToManyField(Skill, blank=True) objects = HorillaCompanyManager() default = models.manager.Manager() + optional_profile_image = models.BooleanField( + default=False, help_text=_("Profile image not mandatory for candidate creation") + ) + optional_resume = models.BooleanField( + default=False, help_text=_("Resume not mandatory for candidate creation") + ) class Meta: """ diff --git a/recruitment/scheduler.py b/recruitment/scheduler.py index 26df11185..a69596a59 100644 --- a/recruitment/scheduler.py +++ b/recruitment/scheduler.py @@ -11,10 +11,11 @@ today = datetime.now() def recruitment_close(): from recruitment.models import Recruitment + today_date = today.date() - - recruitments = Recruitment.objects.filter(closed = False) - + + recruitments = Recruitment.objects.filter(closed=False) + for rec in recruitments: if rec.end_date: if rec.end_date == today_date: @@ -22,6 +23,7 @@ def recruitment_close(): rec.is_published = False rec.save() + scheduler = BackgroundScheduler() scheduler.add_job(recruitment_close, "interval", hours=1) diff --git a/recruitment/templates/candidate/application_form.html b/recruitment/templates/candidate/application_form.html index 3f9b1f926..d7faa748c 100644 --- a/recruitment/templates/candidate/application_form.html +++ b/recruitment/templates/candidate/application_form.html @@ -202,7 +202,7 @@
- {% if resume.file %} diff --git a/recruitment/templates/pipeline/components/candidate_stage_component.html b/recruitment/templates/pipeline/components/candidate_stage_component.html index da5b2c7da..d7427bd1d 100644 --- a/recruitment/templates/pipeline/components/candidate_stage_component.html +++ b/recruitment/templates/pipeline/components/candidate_stage_component.html @@ -278,10 +278,11 @@ style="flex: 1 0 auto; width:20px;height: 40.68px; padding: 0;"> - + name="document-outline"> +
@@ -289,6 +290,7 @@ +ffff