update
This commit is contained in:
166
gnx-react/backend/career/models.py
Normal file
166
gnx-react/backend/career/models.py
Normal file
@@ -0,0 +1,166 @@
|
||||
from django.db import models
|
||||
from django.utils.text import slugify
|
||||
from django.core.validators import FileExtensionValidator
|
||||
|
||||
|
||||
class JobPosition(models.Model):
|
||||
"""Model for job positions/openings"""
|
||||
|
||||
EMPLOYMENT_TYPE_CHOICES = [
|
||||
('full-time', 'Full Time'),
|
||||
('part-time', 'Part Time'),
|
||||
('contract', 'Contract'),
|
||||
('internship', 'Internship'),
|
||||
('remote', 'Remote'),
|
||||
]
|
||||
|
||||
LOCATION_TYPE_CHOICES = [
|
||||
('remote', 'Remote'),
|
||||
('on-site', 'On-site'),
|
||||
('hybrid', 'Hybrid'),
|
||||
]
|
||||
|
||||
STATUS_CHOICES = [
|
||||
('active', 'Active'),
|
||||
('closed', 'Closed'),
|
||||
('draft', 'Draft'),
|
||||
]
|
||||
|
||||
# Basic Information
|
||||
title = models.CharField(max_length=255, help_text="Job title")
|
||||
slug = models.SlugField(max_length=255, unique=True, blank=True)
|
||||
department = models.CharField(max_length=100, blank=True, help_text="Department or category")
|
||||
|
||||
# Employment Details
|
||||
employment_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=EMPLOYMENT_TYPE_CHOICES,
|
||||
default='full-time'
|
||||
)
|
||||
location_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=LOCATION_TYPE_CHOICES,
|
||||
default='remote'
|
||||
)
|
||||
location = models.CharField(max_length=255, default='Remote', help_text="Work location")
|
||||
|
||||
# Position Details
|
||||
open_positions = models.PositiveIntegerField(default=1, help_text="Number of open positions")
|
||||
experience_required = models.CharField(max_length=100, blank=True, help_text="e.g., 3+ years")
|
||||
|
||||
# Salary Information
|
||||
salary_min = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
salary_max = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
salary_currency = models.CharField(max_length=10, default='USD')
|
||||
salary_period = models.CharField(max_length=20, default='per month', help_text="e.g., per month, per year")
|
||||
salary_additional = models.TextField(blank=True, help_text="Additional salary info like bonuses, benefits")
|
||||
|
||||
# Job Description
|
||||
short_description = models.TextField(blank=True, help_text="Brief description for listing page")
|
||||
about_role = models.TextField(blank=True, help_text="About this role / Who we are")
|
||||
requirements = models.JSONField(default=list, blank=True, help_text="List of requirements")
|
||||
responsibilities = models.JSONField(default=list, blank=True, help_text="List of responsibilities")
|
||||
qualifications = models.JSONField(default=list, blank=True, help_text="List of qualifications")
|
||||
bonus_points = models.JSONField(default=list, blank=True, help_text="Nice to have skills")
|
||||
benefits = models.JSONField(default=list, blank=True, help_text="What you get")
|
||||
|
||||
# Dates and Status
|
||||
start_date = models.CharField(max_length=100, default='ASAP', help_text="Expected start date")
|
||||
posted_date = models.DateTimeField(auto_now_add=True)
|
||||
updated_date = models.DateTimeField(auto_now=True)
|
||||
deadline = models.DateTimeField(null=True, blank=True, help_text="Application deadline")
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active')
|
||||
|
||||
# SEO and Metadata
|
||||
featured = models.BooleanField(default=False, help_text="Feature this job on homepage")
|
||||
priority = models.IntegerField(default=0, help_text="Higher number = higher priority in listing")
|
||||
|
||||
class Meta:
|
||||
ordering = ['-priority', '-posted_date']
|
||||
verbose_name = 'Job Position'
|
||||
verbose_name_plural = 'Job Positions'
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title} ({self.open_positions} positions)"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify(self.title)
|
||||
# Ensure unique slug
|
||||
original_slug = self.slug
|
||||
counter = 1
|
||||
while JobPosition.objects.filter(slug=self.slug).exists():
|
||||
self.slug = f"{original_slug}-{counter}"
|
||||
counter += 1
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class JobApplication(models.Model):
|
||||
"""Model for job applications"""
|
||||
|
||||
STATUS_CHOICES = [
|
||||
('new', 'New'),
|
||||
('reviewing', 'Reviewing'),
|
||||
('shortlisted', 'Shortlisted'),
|
||||
('interviewed', 'Interviewed'),
|
||||
('accepted', 'Accepted'),
|
||||
('rejected', 'Rejected'),
|
||||
]
|
||||
|
||||
# Related Job
|
||||
job = models.ForeignKey(JobPosition, on_delete=models.CASCADE, related_name='applications')
|
||||
|
||||
# Applicant Information
|
||||
first_name = models.CharField(max_length=100)
|
||||
last_name = models.CharField(max_length=100)
|
||||
email = models.EmailField()
|
||||
phone = models.CharField(max_length=20, blank=True)
|
||||
|
||||
# Professional Information
|
||||
current_position = models.CharField(max_length=255, blank=True, help_text="Current job title")
|
||||
current_company = models.CharField(max_length=255, blank=True)
|
||||
years_of_experience = models.CharField(max_length=50, blank=True)
|
||||
|
||||
# Application Details
|
||||
cover_letter = models.TextField(blank=True, help_text="Cover letter or message")
|
||||
resume = models.FileField(
|
||||
upload_to='career/resumes/%Y/%m/',
|
||||
validators=[FileExtensionValidator(allowed_extensions=['pdf', 'doc', 'docx'])],
|
||||
help_text="Upload your resume (PDF, DOC, DOCX)"
|
||||
)
|
||||
portfolio_url = models.URLField(blank=True, help_text="Link to portfolio or LinkedIn")
|
||||
|
||||
# Additional Information
|
||||
linkedin_url = models.URLField(blank=True)
|
||||
github_url = models.URLField(blank=True)
|
||||
website_url = models.URLField(blank=True)
|
||||
|
||||
# Availability
|
||||
available_from = models.DateField(null=True, blank=True, help_text="When can you start?")
|
||||
notice_period = models.CharField(max_length=100, blank=True, help_text="Notice period if applicable")
|
||||
|
||||
# Salary Expectations
|
||||
expected_salary = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
salary_currency = models.CharField(max_length=10, default='USD')
|
||||
|
||||
# Application Metadata
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='new')
|
||||
applied_date = models.DateTimeField(auto_now_add=True)
|
||||
updated_date = models.DateTimeField(auto_now=True)
|
||||
notes = models.TextField(blank=True, help_text="Internal notes (not visible to applicant)")
|
||||
|
||||
# Privacy
|
||||
consent = models.BooleanField(default=False, help_text="Consent to data processing")
|
||||
|
||||
class Meta:
|
||||
ordering = ['-applied_date']
|
||||
verbose_name = 'Job Application'
|
||||
verbose_name_plural = 'Job Applications'
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name} - {self.job.title}"
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
Reference in New Issue
Block a user