Files
ihrm/recruitment/models.py

257 lines
7.8 KiB
Python
Raw Normal View History

"""
models.py
This module is used to register models for recruitment app
"""
import os
2023-05-10 15:06:57 +05:30
import django
from django.db import models
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from simple_history.models import HistoricalRecords
from employee.models import Employee
from base.models import JobPosition, Company
2023-05-10 15:06:57 +05:30
# Create your models here.
2023-05-10 15:06:57 +05:30
def validate_pdf(value):
"""
This method is used to validate pdf
"""
ext = os.path.splitext(value.name)[1] # Get file extension
if ext.lower() != ".pdf":
raise ValidationError("File must be a PDF.")
2023-05-10 15:06:57 +05:30
def validate_image(value):
"""
This method is used to validate the image
"""
return value
2023-05-10 15:06:57 +05:30
class Recruitment(models.Model):
"""
Recruitment model
"""
title = models.CharField(max_length=30, null=True, blank=True)
2023-05-10 15:06:57 +05:30
description = models.TextField(null=True)
is_event_based = models.BooleanField(default=False)
open_positions = models.ManyToManyField(
JobPosition, related_name="open_positions", blank=True
)
2023-05-10 15:06:57 +05:30
job_position_id = models.ForeignKey(
JobPosition,
on_delete=models.CASCADE,
null=True,
blank=True,
db_constraint=False,
related_name="recruitment",
verbose_name="Job Position",
)
2023-05-10 15:06:57 +05:30
vacancy = models.IntegerField(blank=True, null=True)
recruitment_managers = models.ManyToManyField(Employee)
company_id = models.ForeignKey(
Company,
on_delete=models.DO_NOTHING,
null=True,
blank=True,
verbose_name="Company",
)
2023-05-10 15:06:57 +05:30
start_date = models.DateField(default=django.utils.timezone.now)
end_date = models.DateField(blank=True, null=True)
closed = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
objects = models.Manager()
2023-05-10 15:06:57 +05:30
class Meta:
"""
Meta class to add the additional info
"""
unique_together = [
(
"job_position_id",
"start_date",
),
("job_position_id", "start_date", "company_id"),
]
permissions = (("archive_recruitment", "Archive Recruitment"),)
2023-05-10 15:06:57 +05:30
def __str__(self):
title = (
f"{self.job_position_id.job_position} {self.start_date}"
if self.title is None and self.job_position_id
else self.title
)
if not self.is_event_based and self.job_position_id is not None:
self.open_positions.add(self.job_position_id)
return title
def clean(self):
if self.title is None:
raise ValidationError({"title": "This field is required"})
if not self.is_event_based and self.job_position_id is None:
raise ValidationError({"job_position_id": "This field is required"})
return super().clean()
def save(self, *args, **kwargs):
super().save(*args, **kwargs) # Save the Recruitment instance first
if self.is_event_based and self.open_positions is None:
raise ValidationError({"open_positions": "This field is required"})
2023-05-10 15:06:57 +05:30
class Stage(models.Model):
"""
Stage model
"""
2023-05-10 15:06:57 +05:30
stage_types = [
("initial", _("Initial")),
("test", _("Test")),
("interview", _("Interview")),
("hired", _("Hired")),
2023-05-10 15:06:57 +05:30
]
recruitment_id = models.ForeignKey(
Recruitment,
on_delete=models.CASCADE,
related_name="stage_set",
verbose_name="Recruitment",
)
stage_managers = models.ManyToManyField(Employee, blank=True)
stage = models.CharField(max_length=50)
stage_type = models.CharField(
max_length=20, choices=stage_types, default="interview"
)
2023-05-10 15:06:57 +05:30
sequence = models.IntegerField(null=True)
is_active = models.BooleanField(default=True)
objects = models.Manager()
2023-05-10 15:06:57 +05:30
def __str__(self):
return f"{self.stage}"
2023-05-10 15:06:57 +05:30
class Meta:
"""
Meta class to add the additional info
"""
permissions = (("archive_Stage", "Archive Stage"),)
unique_together = ["recruitment_id", "stage"]
2023-05-10 15:06:57 +05:30
class Candidate(models.Model):
"""
Candidate model
"""
choices = [("male", _("Male")), ("female", _("Female")), ("other", _("Other"))]
name = models.CharField(max_length=100, null=True)
profile = models.ImageField(
upload_to="recruitment/profile",
null=True,
)
portfolio = models.URLField(max_length=200, blank=True)
recruitment_id = models.ForeignKey(
Recruitment,
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="candidate",
verbose_name="Recruitment",
)
job_position_id = models.ForeignKey(
JobPosition, on_delete=models.CASCADE, null=True, blank=True
)
stage_id = models.ForeignKey(
Stage, on_delete=models.CASCADE, null=True, verbose_name="Stage"
)
schedule_date = models.DateTimeField(blank=True, null=True)
email = models.EmailField(
max_length=254,
unique=True,
)
2023-05-10 15:06:57 +05:30
mobile = models.CharField(max_length=15, blank=True)
resume = models.FileField(
upload_to="recruitment/resume",
validators=[
validate_pdf,
],
)
referral = models.ForeignKey(
Employee,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="candidate_referral",
)
address = models.TextField(null=True, blank=True)
country = models.CharField(max_length=30, null=True, blank=True)
dob = models.DateField(null=True, blank=True)
state = models.CharField(max_length=30, null=True, blank=True)
city = models.CharField(max_length=30, null=True, blank=True)
zip = models.CharField(max_length=30, null=True, blank=True)
gender = models.CharField(max_length=15, choices=choices, null=True)
2023-05-10 15:06:57 +05:30
start_onboard = models.BooleanField(default=False)
hired = models.BooleanField(default=False)
canceled = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
joining_date = models.DateField(blank=True, null=True)
2023-05-10 15:06:57 +05:30
history = HistoricalRecords(
related_name="candidate_history",
2023-05-10 15:06:57 +05:30
)
sequence = models.IntegerField(null=True,default=0)
objects = models.Manager()
2023-05-10 15:06:57 +05:30
def __str__(self):
return f"{self.name}"
2023-05-10 15:06:57 +05:30
def save(self, *args, **kwargs):
# Check if the 'stage_id' attribute is not None
if self.stage_id is not None:
# Check if the stage type is 'hired'
if self.stage_id.stage_type == "hired":
self.hired = True
if not self.recruitment_id.is_event_based and self.job_position_id is None:
self.job_position_id = self.recruitment_id.job_position_id
if self.job_position_id not in self.recruitment_id.open_positions.all():
raise ValidationError({"job_position_id": "Choose valid choice"})
if self.recruitment_id.is_event_based and self.job_position_id is None:
raise ValidationError({"job_position_id": "This field is required."})
super().save(*args, **kwargs)
2023-05-10 15:06:57 +05:30
class Meta:
"""
Meta class to add the additional info
"""
2023-05-10 15:06:57 +05:30
unique_together = (
"email",
"recruitment_id",
)
permissions = (
("view_history", "View Candidate History"),
("archive_candidate", "Archive Candidate"),
)
ordering = ["sequence"]
2023-05-10 15:06:57 +05:30
class StageNote(models.Model):
"""
StageNote model
"""
2023-05-10 15:06:57 +05:30
candidate_id = models.ForeignKey(Candidate, on_delete=models.CASCADE)
title = models.CharField(max_length=50, null=True)
description = models.TextField()
stage_id = models.ForeignKey(Stage, on_delete=models.CASCADE)
updated_by = models.ForeignKey(Employee, on_delete=models.CASCADE)
objects = models.Manager()
2023-05-10 15:06:57 +05:30
def __str__(self) -> str:
return f"{self.description}"