fix error
This commit is contained in:
parent
5921e30396
commit
2dd90e4d38
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,600 +0,0 @@
|
||||
# Generated by Django 5.2.6 on 2025-10-19 18:40
|
||||
|
||||
import django.core.validators
|
||||
import django.db.models.deletion
|
||||
import django_ckeditor_5.fields
|
||||
import django_countries.fields
|
||||
import django_extensions.db.fields
|
||||
import recruitment.validators
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BreakTime',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('start_time', models.TimeField(verbose_name='Start Time')),
|
||||
('end_time', models.TimeField(verbose_name='End Time')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FormStage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('name', models.CharField(help_text='Name of the stage', max_length=200)),
|
||||
('order', models.PositiveIntegerField(default=0, help_text='Order of the stage in the form')),
|
||||
('is_predefined', models.BooleanField(default=False, help_text='Whether this is a default resume stage')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Form Stage',
|
||||
'verbose_name_plural': 'Form Stages',
|
||||
'ordering': ['order'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HiringAgency',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('name', models.CharField(max_length=200, unique=True, verbose_name='Agency Name')),
|
||||
('contact_person', models.CharField(blank=True, max_length=150, verbose_name='Contact Person')),
|
||||
('email', models.EmailField(blank=True, max_length=254)),
|
||||
('phone', models.CharField(blank=True, max_length=20)),
|
||||
('website', models.URLField(blank=True)),
|
||||
('notes', models.TextField(blank=True, help_text='Internal notes about the agency')),
|
||||
('country', django_countries.fields.CountryField(blank=True, max_length=2, null=True)),
|
||||
('address', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Hiring Agency',
|
||||
'verbose_name_plural': 'Hiring Agencies',
|
||||
'ordering': ['name'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Source',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('name', models.CharField(help_text='e.g., ATS, ERP ', max_length=100, unique=True, verbose_name='Source Name')),
|
||||
('source_type', models.CharField(help_text='e.g., ATS, ERP ', max_length=100, verbose_name='Source Type')),
|
||||
('description', models.TextField(blank=True, help_text='A description of the source', verbose_name='Description')),
|
||||
('ip_address', models.GenericIPAddressField(blank=True, help_text='The IP address of the source', null=True, verbose_name='IP Address')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('api_key', models.CharField(blank=True, help_text='API key for authentication (will be encrypted)', max_length=255, null=True, verbose_name='API Key')),
|
||||
('api_secret', models.CharField(blank=True, help_text='API secret for authentication (will be encrypted)', max_length=255, null=True, verbose_name='API Secret')),
|
||||
('trusted_ips', models.TextField(blank=True, help_text='Comma-separated list of trusted IP addresses', null=True, verbose_name='Trusted IP Addresses')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Whether this source is active for integration', verbose_name='Active')),
|
||||
('integration_version', models.CharField(blank=True, help_text='Version of the integration protocol', max_length=50, verbose_name='Integration Version')),
|
||||
('last_sync_at', models.DateTimeField(blank=True, help_text='Timestamp of the last successful synchronization', null=True, verbose_name='Last Sync At')),
|
||||
('sync_status', models.CharField(blank=True, choices=[('IDLE', 'Idle'), ('SYNCING', 'Syncing'), ('ERROR', 'Error'), ('DISABLED', 'Disabled')], default='IDLE', max_length=20, verbose_name='Sync Status')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Source',
|
||||
'verbose_name_plural': 'Sources',
|
||||
'ordering': ['name'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ZoomMeeting',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('topic', models.CharField(max_length=255, verbose_name='Topic')),
|
||||
('meeting_id', models.CharField(db_index=True, max_length=20, unique=True, verbose_name='Meeting ID')),
|
||||
('start_time', models.DateTimeField(db_index=True, verbose_name='Start Time')),
|
||||
('meeting_id', models.CharField(db_index=True, max_length=20, unique=True, verbose_name='Meeting ID')),
|
||||
('start_time', models.DateTimeField(db_index=True, verbose_name='Start Time')),
|
||||
('duration', models.PositiveIntegerField(verbose_name='Duration')),
|
||||
('timezone', models.CharField(max_length=50, verbose_name='Timezone')),
|
||||
('join_url', models.URLField(verbose_name='Join URL')),
|
||||
('participant_video', models.BooleanField(default=True, verbose_name='Participant Video')),
|
||||
('password', models.CharField(blank=True, max_length=20, null=True, verbose_name='Password')),
|
||||
('join_before_host', models.BooleanField(default=False, verbose_name='Join Before Host')),
|
||||
('mute_upon_entry', models.BooleanField(default=False, verbose_name='Mute Upon Entry')),
|
||||
('waiting_room', models.BooleanField(default=False, verbose_name='Waiting Room')),
|
||||
('zoom_gateway_response', models.JSONField(blank=True, null=True, verbose_name='Zoom Gateway Response')),
|
||||
('status', models.CharField(blank=True, db_index=True, default='waiting', max_length=20, null=True, verbose_name='Status')),
|
||||
('status', models.CharField(blank=True, db_index=True, default='waiting', max_length=20, null=True, verbose_name='Status')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FormField',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('label', models.CharField(help_text='Label for the field', max_length=200)),
|
||||
('field_type', models.CharField(choices=[('text', 'Text Input'), ('email', 'Email'), ('phone', 'Phone'), ('textarea', 'Text Area'), ('file', 'File Upload'), ('date', 'Date Picker'), ('select', 'Dropdown'), ('radio', 'Radio Buttons'), ('checkbox', 'Checkboxes')], help_text='Type of the field', max_length=20)),
|
||||
('placeholder', models.CharField(blank=True, help_text='Placeholder text', max_length=200)),
|
||||
('required', models.BooleanField(default=False, help_text='Whether the field is required')),
|
||||
('order', models.PositiveIntegerField(default=0, help_text='Order of the field in the stage')),
|
||||
('is_predefined', models.BooleanField(default=False, help_text='Whether this is a default field')),
|
||||
('options', models.JSONField(blank=True, default=list, help_text='Options for selection fields (stored as JSON array)')),
|
||||
('file_types', models.CharField(blank=True, help_text="Allowed file types (comma-separated, e.g., '.pdf,.doc,.docx')", max_length=200)),
|
||||
('max_file_size', models.PositiveIntegerField(default=5, help_text='Maximum file size in MB (default: 5MB)')),
|
||||
('multiple_files', models.BooleanField(default=False, help_text='Allow multiple files to be uploaded')),
|
||||
('max_files', models.PositiveIntegerField(default=1, help_text='Maximum number of files allowed (when multiple_files is True)')),
|
||||
('stage', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='recruitment.formstage')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Form Field',
|
||||
'verbose_name_plural': 'Form Fields',
|
||||
'ordering': ['order'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FormTemplate',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('name', models.CharField(help_text='Name of the form template', max_length=200)),
|
||||
('description', models.TextField(blank=True, help_text='Description of the form template')),
|
||||
('is_active', models.BooleanField(default=False, help_text='Whether this template is active')),
|
||||
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='form_templates', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Form Template',
|
||||
'verbose_name_plural': 'Form Templates',
|
||||
'ordering': ['-created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FormSubmission',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('submitted_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
||||
('applicant_name', models.CharField(blank=True, help_text='Name of the applicant', max_length=200)),
|
||||
('applicant_email', models.EmailField(blank=True, db_index=True, help_text='Email of the applicant', max_length=254)),
|
||||
('submitted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='form_submissions', to=settings.AUTH_USER_MODEL)),
|
||||
('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submissions', to='recruitment.formtemplate')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Form Submission',
|
||||
'verbose_name_plural': 'Form Submissions',
|
||||
'ordering': ['-submitted_at'],
|
||||
},
|
||||
migrations.CreateModel(
|
||||
name='FormSubmission',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('submitted_at', models.DateTimeField(auto_now_add=True, db_index=True)),
|
||||
('applicant_name', models.CharField(blank=True, help_text='Name of the applicant', max_length=200)),
|
||||
('applicant_email', models.EmailField(blank=True, db_index=True, help_text='Email of the applicant', max_length=254)),
|
||||
('submitted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='form_submissions', to=settings.AUTH_USER_MODEL)),
|
||||
('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submissions', to='recruitment.formtemplate')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Form Submission',
|
||||
'verbose_name_plural': 'Form Submissions',
|
||||
'ordering': ['-submitted_at'],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='formstage',
|
||||
name='template',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stages', to='recruitment.formtemplate'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Candidate',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('first_name', models.CharField(max_length=255, verbose_name='First Name')),
|
||||
('last_name', models.CharField(max_length=255, verbose_name='Last Name')),
|
||||
('email', models.EmailField(db_index=True, max_length=254, verbose_name='Email')),
|
||||
('email', models.EmailField(db_index=True, max_length=254, verbose_name='Email')),
|
||||
('phone', models.CharField(max_length=20, verbose_name='Phone')),
|
||||
('address', models.TextField(max_length=200, verbose_name='Address')),
|
||||
('resume', models.FileField(upload_to='resumes/', verbose_name='Resume')),
|
||||
('is_resume_parsed', models.BooleanField(default=False, verbose_name='Resume Parsed')),
|
||||
('is_potential_candidate', models.BooleanField(default=False, verbose_name='Potential Candidate')),
|
||||
('parsed_summary', models.TextField(blank=True, verbose_name='Parsed Summary')),
|
||||
('applied', models.BooleanField(default=False, verbose_name='Applied')),
|
||||
('stage', models.CharField(choices=[('Applied', 'Applied'), ('Exam', 'Exam'), ('Interview', 'Interview'), ('Offer', 'Offer')], db_index=True, default='Applied', max_length=100, verbose_name='Stage')),
|
||||
('stage', models.CharField(choices=[('Applied', 'Applied'), ('Exam', 'Exam'), ('Interview', 'Interview'), ('Offer', 'Offer')], db_index=True, default='Applied', max_length=100, verbose_name='Stage')),
|
||||
('applicant_status', models.CharField(blank=True, choices=[('Applicant', 'Applicant'), ('Candidate', 'Candidate')], default='Applicant', max_length=100, null=True, verbose_name='Applicant Status')),
|
||||
('exam_date', models.DateTimeField(blank=True, null=True, verbose_name='Exam Date')),
|
||||
('exam_status', models.CharField(blank=True, choices=[('Passed', 'Passed'), ('Failed', 'Failed')], max_length=100, null=True, verbose_name='Exam Status')),
|
||||
('interview_date', models.DateTimeField(blank=True, null=True, verbose_name='Interview Date')),
|
||||
('interview_status', models.CharField(blank=True, choices=[('Passed', 'Passed'), ('Failed', 'Failed')], max_length=100, null=True, verbose_name='Interview Status')),
|
||||
('interview_status', models.CharField(blank=True, choices=[('Passed', 'Passed'), ('Failed', 'Failed')], max_length=100, null=True, verbose_name='Interview Status')),
|
||||
('offer_date', models.DateField(blank=True, null=True, verbose_name='Offer Date')),
|
||||
('offer_status', models.CharField(blank=True, choices=[('Accepted', 'Accepted'), ('Rejected', 'Rejected')], max_length=100, null=True, verbose_name='Offer Status')),
|
||||
('join_date', models.DateField(blank=True, null=True, verbose_name='Join Date')),
|
||||
('ai_analysis_data', models.JSONField(default=dict, help_text='Full JSON output from the resume scoring model.', verbose_name='AI Analysis Data')),
|
||||
('ai_analysis_data', models.JSONField(default=dict, help_text='Full JSON output from the resume scoring model.', verbose_name='AI Analysis Data')),
|
||||
('submitted_by_agency', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_candidates', to='recruitment.hiringagency', verbose_name='Submitted by Agency')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Candidate',
|
||||
'verbose_name_plural': 'Candidates',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='JobPosting',
|
||||
fields=[
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('title', models.CharField(max_length=200)),
|
||||
('department', models.CharField(blank=True, max_length=100)),
|
||||
('job_type', models.CharField(choices=[('FULL_TIME', 'Full-time'), ('PART_TIME', 'Part-time'), ('CONTRACT', 'Contract'), ('INTERNSHIP', 'Internship'), ('FACULTY', 'Faculty'), ('TEMPORARY', 'Temporary')], default='FULL_TIME', max_length=20)),
|
||||
('workplace_type', models.CharField(choices=[('ON_SITE', 'On-site'), ('REMOTE', 'Remote'), ('HYBRID', 'Hybrid')], default='ON_SITE', max_length=20)),
|
||||
('location_city', models.CharField(blank=True, max_length=100)),
|
||||
('location_state', models.CharField(blank=True, max_length=100)),
|
||||
('location_country', models.CharField(default='Saudia Arabia', max_length=100)),
|
||||
('description', django_ckeditor_5.fields.CKEditor5Field(verbose_name='Description')),
|
||||
('qualifications', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)),
|
||||
('salary_range', models.CharField(blank=True, help_text='e.g., $60,000 - $80,000', max_length=200)),
|
||||
('benefits', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)),
|
||||
('application_url', models.URLField(blank=True, help_text='URL where candidates apply', null=True, validators=[django.core.validators.URLValidator()])),
|
||||
('application_start_date', models.DateField(blank=True, null=True)),
|
||||
('application_deadline', models.DateField(blank=True, db_index=True, null=True)),
|
||||
('application_deadline', models.DateField(blank=True, db_index=True, null=True)),
|
||||
('application_instructions', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)),
|
||||
('internal_job_id', models.CharField(editable=False, max_length=50, primary_key=True, serialize=False)),
|
||||
('created_by', models.CharField(blank=True, help_text='Name of person who created this job', max_length=100)),
|
||||
('status', models.CharField(choices=[('DRAFT', 'Draft'), ('ACTIVE', 'Active'), ('CLOSED', 'Closed'), ('CANCELLED', 'Cancelled'), ('ARCHIVED', 'Archived')], db_index=True, default='DRAFT', max_length=20)),
|
||||
('status', models.CharField(choices=[('DRAFT', 'Draft'), ('ACTIVE', 'Active'), ('CLOSED', 'Closed'), ('CANCELLED', 'Cancelled'), ('ARCHIVED', 'Archived')], db_index=True, default='DRAFT', max_length=20)),
|
||||
('hash_tags', models.CharField(blank=True, help_text='Comma-separated hashtags for linkedin post like #hiring,#jobopening', max_length=200, validators=[recruitment.validators.validate_hash_tags])),
|
||||
('linkedin_post_id', models.CharField(blank=True, help_text='LinkedIn post ID after posting', max_length=200)),
|
||||
('linkedin_post_url', models.URLField(blank=True, help_text='Direct URL to LinkedIn post')),
|
||||
('posted_to_linkedin', models.BooleanField(default=False)),
|
||||
('linkedin_post_status', models.CharField(blank=True, help_text='Status of LinkedIn posting', max_length=50)),
|
||||
('linkedin_posted_at', models.DateTimeField(blank=True, null=True)),
|
||||
('published_at', models.DateTimeField(blank=True, db_index=True, null=True)),
|
||||
('published_at', models.DateTimeField(blank=True, db_index=True, null=True)),
|
||||
('position_number', models.CharField(blank=True, help_text='University position number', max_length=50)),
|
||||
('reporting_to', models.CharField(blank=True, help_text='Who this position reports to', max_length=100)),
|
||||
('joining_date', models.DateField(blank=True, help_text='Desired start date', null=True)),
|
||||
('open_positions', models.PositiveIntegerField(default=1, help_text='Number of open positions for this job')),
|
||||
('max_applications', models.PositiveIntegerField(blank=True, default=1000, help_text='Maximum number of applications allowed', null=True)),
|
||||
('max_applications', models.PositiveIntegerField(blank=True, default=1000, help_text='Maximum number of applications allowed', null=True)),
|
||||
('cancel_reason', models.TextField(blank=True, help_text='Reason for canceling the job posting', verbose_name='Cancel Reason')),
|
||||
('cancelled_by', models.CharField(blank=True, help_text='Name of person who cancelled this job', max_length=100, verbose_name='Cancelled By')),
|
||||
('cancelled_at', models.DateTimeField(blank=True, null=True)),
|
||||
('hiring_agency', models.ManyToManyField(blank=True, help_text='External agency responsible for sourcing candidates for this role', related_name='jobs', to='recruitment.hiringagency', verbose_name='Hiring Agency')),
|
||||
('source', models.ForeignKey(blank=True, help_text='The system or channel from which this job posting originated or was first published.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='job_postings', to='recruitment.source')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Job Posting',
|
||||
'verbose_name_plural': 'Job Postings',
|
||||
'ordering': ['-created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='InterviewSchedule',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('start_date', models.DateField(db_index=True, verbose_name='Start Date')),
|
||||
('end_date', models.DateField(db_index=True, verbose_name='End Date')),
|
||||
('start_date', models.DateField(db_index=True, verbose_name='Start Date')),
|
||||
('end_date', models.DateField(db_index=True, verbose_name='End Date')),
|
||||
('working_days', models.JSONField(verbose_name='Working Days')),
|
||||
('start_time', models.TimeField(verbose_name='Start Time')),
|
||||
('end_time', models.TimeField(verbose_name='End Time')),
|
||||
('break_start_time', models.TimeField(blank=True, null=True, verbose_name='Break Start Time')),
|
||||
('break_end_time', models.TimeField(blank=True, null=True, verbose_name='Break End Time')),
|
||||
('break_start_time', models.TimeField(blank=True, null=True, verbose_name='Break Start Time')),
|
||||
('break_end_time', models.TimeField(blank=True, null=True, verbose_name='Break End Time')),
|
||||
('interview_duration', models.PositiveIntegerField(verbose_name='Interview Duration (minutes)')),
|
||||
('buffer_time', models.PositiveIntegerField(default=0, verbose_name='Buffer Time (minutes)')),
|
||||
('candidates', models.ManyToManyField(blank=True, null=True, related_name='interview_schedules', to='recruitment.candidate')),
|
||||
('candidates', models.ManyToManyField(blank=True, null=True, related_name='interview_schedules', to='recruitment.candidate')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interview_schedules', to='recruitment.jobposting')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='formtemplate',
|
||||
name='job',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='form_template', to='recruitment.jobposting'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='candidate',
|
||||
name='job',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='recruitment.jobposting', verbose_name='Job'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='JobPostingImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('post_image', models.ImageField(upload_to='post/', validators=[recruitment.validators.validate_image_size])),
|
||||
('job', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='post_images', to='recruitment.jobposting')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('profile_image', models.ImageField(blank=True, null=True, upload_to='profile_pic/')),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SharedFormTemplate',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('is_public', models.BooleanField(default=False, help_text='Whether this template is publicly available')),
|
||||
('shared_with', models.ManyToManyField(blank=True, related_name='shared_templates', to=settings.AUTH_USER_MODEL)),
|
||||
('template', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='recruitment.formtemplate')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Shared Form Template',
|
||||
'verbose_name_plural': 'Shared Form Templates',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='IntegrationLog',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('action', models.CharField(choices=[('REQUEST', 'Request'), ('RESPONSE', 'Response'), ('ERROR', 'Error'), ('SYNC', 'Sync'), ('CREATE_JOB', 'Create Job'), ('UPDATE_JOB', 'Update Job')], max_length=20, verbose_name='Action')),
|
||||
('endpoint', models.CharField(blank=True, max_length=255, verbose_name='Endpoint')),
|
||||
('method', models.CharField(blank=True, max_length=10, verbose_name='HTTP Method')),
|
||||
('request_data', models.JSONField(blank=True, null=True, verbose_name='Request Data')),
|
||||
('response_data', models.JSONField(blank=True, null=True, verbose_name='Response Data')),
|
||||
('status_code', models.CharField(blank=True, max_length=10, verbose_name='Status Code')),
|
||||
('error_message', models.TextField(blank=True, verbose_name='Error Message')),
|
||||
('ip_address', models.GenericIPAddressField(verbose_name='IP Address')),
|
||||
('user_agent', models.CharField(blank=True, max_length=255, verbose_name='User Agent')),
|
||||
('processing_time', models.FloatField(blank=True, null=True, verbose_name='Processing Time (seconds)')),
|
||||
('source', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='integration_logs', to='recruitment.source', verbose_name='Source')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Integration Log',
|
||||
'verbose_name_plural': 'Integration Logs',
|
||||
'ordering': ['-created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrainingMaterial',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('title', models.CharField(max_length=255, verbose_name='Title')),
|
||||
('content', django_ckeditor_5.fields.CKEditor5Field(blank=True, verbose_name='Content')),
|
||||
('video_link', models.URLField(blank=True, verbose_name='Video Link')),
|
||||
('file', models.FileField(blank=True, upload_to='training_materials/', verbose_name='File')),
|
||||
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created by')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Training Material',
|
||||
'verbose_name_plural': 'Training Materials',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ScheduledInterview',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('interview_date', models.DateField(db_index=True, verbose_name='Interview Date')),
|
||||
('interview_date', models.DateField(db_index=True, verbose_name='Interview Date')),
|
||||
('interview_time', models.TimeField(verbose_name='Interview Time')),
|
||||
('status', models.CharField(choices=[('scheduled', 'Scheduled'), ('confirmed', 'Confirmed'), ('cancelled', 'Cancelled'), ('completed', 'Completed')], db_index=True, default='scheduled', max_length=20)),
|
||||
('status', models.CharField(choices=[('scheduled', 'Scheduled'), ('confirmed', 'Confirmed'), ('cancelled', 'Cancelled'), ('completed', 'Completed')], db_index=True, default='scheduled', max_length=20)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('candidate', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='scheduled_interviews', to='recruitment.candidate')),
|
||||
('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='scheduled_interviews', to='recruitment.jobposting')),
|
||||
('schedule', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='interviews', to='recruitment.interviewschedule')),
|
||||
('zoom_meeting', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='interview', to='recruitment.zoommeeting')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='MeetingComment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('content', django_ckeditor_5.fields.CKEditor5Field(verbose_name='Content')),
|
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='meeting_comments', to=settings.AUTH_USER_MODEL, verbose_name='Author')),
|
||||
('meeting', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='recruitment.zoommeeting', verbose_name='Meeting')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Meeting Comment',
|
||||
'verbose_name_plural': 'Meeting Comments',
|
||||
'ordering': ['-created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FieldResponse',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('value', models.JSONField(blank=True, help_text='Response value (stored as JSON)', null=True)),
|
||||
('uploaded_file', models.FileField(blank=True, null=True, upload_to='form_uploads/')),
|
||||
('field', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='recruitment.formfield')),
|
||||
('submission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='recruitment.formsubmission')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='MeetingComment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('content', django_ckeditor_5.fields.CKEditor5Field(verbose_name='Content')),
|
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='meeting_comments', to=settings.AUTH_USER_MODEL, verbose_name='Author')),
|
||||
('meeting', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='recruitment.zoommeeting', verbose_name='Meeting')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Meeting Comment',
|
||||
'verbose_name_plural': 'Meeting Comments',
|
||||
'ordering': ['-created_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FieldResponse',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('value', models.JSONField(blank=True, help_text='Response value (stored as JSON)', null=True)),
|
||||
('uploaded_file', models.FileField(blank=True, null=True, upload_to='form_uploads/')),
|
||||
('field', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='recruitment.formfield')),
|
||||
('submission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='recruitment.formsubmission')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Field Response',
|
||||
'verbose_name_plural': 'Field Responses',
|
||||
'indexes': [models.Index(fields=['submission'], name='recruitment_submiss_474130_idx'), models.Index(fields=['field'], name='recruitment_field_i_097e5b_idx')],
|
||||
'verbose_name': 'Field Response',
|
||||
'verbose_name_plural': 'Field Responses',
|
||||
'indexes': [models.Index(fields=['submission'], name='recruitment_submiss_474130_idx'), models.Index(fields=['field'], name='recruitment_field_i_097e5b_idx')],
|
||||
},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='formsubmission',
|
||||
index=models.Index(fields=['submitted_at'], name='recruitment_submitt_7946c8_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='interviewschedule',
|
||||
index=models.Index(fields=['start_date'], name='recruitment_start_d_15d55e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='interviewschedule',
|
||||
index=models.Index(fields=['end_date'], name='recruitment_end_dat_aeb00e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='interviewschedule',
|
||||
index=models.Index(fields=['created_by'], name='recruitment_created_d0bdcc_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='formtemplate',
|
||||
index=models.Index(fields=['created_at'], name='recruitment_created_c21775_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='formtemplate',
|
||||
index=models.Index(fields=['is_active'], name='recruitment_is_acti_ae5efb_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='candidate',
|
||||
index=models.Index(fields=['stage'], name='recruitment_stage_f1c6eb_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='candidate',
|
||||
index=models.Index(fields=['created_at'], name='recruitment_created_73590f_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='jobposting',
|
||||
index=models.Index(fields=['status', 'created_at', 'title'], name='recruitment_status_8b77aa_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='jobposting',
|
||||
index=models.Index(fields=['slug'], name='recruitment_slug_004045_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='scheduledinterview',
|
||||
index=models.Index(fields=['job', 'status'], name='recruitment_job_id_f09e22_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='scheduledinterview',
|
||||
index=models.Index(fields=['interview_date', 'interview_time'], name='recruitment_intervi_7f5877_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='scheduledinterview',
|
||||
index=models.Index(fields=['candidate', 'job'], name='recruitment_candida_43d5b0_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='formsubmission',
|
||||
index=models.Index(fields=['submitted_at'], name='recruitment_submitt_7946c8_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='interviewschedule',
|
||||
index=models.Index(fields=['start_date'], name='recruitment_start_d_15d55e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='interviewschedule',
|
||||
index=models.Index(fields=['end_date'], name='recruitment_end_dat_aeb00e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='interviewschedule',
|
||||
index=models.Index(fields=['created_by'], name='recruitment_created_d0bdcc_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='formtemplate',
|
||||
index=models.Index(fields=['created_at'], name='recruitment_created_c21775_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='formtemplate',
|
||||
index=models.Index(fields=['is_active'], name='recruitment_is_acti_ae5efb_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='candidate',
|
||||
index=models.Index(fields=['stage'], name='recruitment_stage_f1c6eb_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='candidate',
|
||||
index=models.Index(fields=['created_at'], name='recruitment_created_73590f_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='jobposting',
|
||||
index=models.Index(fields=['status', 'created_at', 'title'], name='recruitment_status_8b77aa_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='jobposting',
|
||||
index=models.Index(fields=['slug'], name='recruitment_slug_004045_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='scheduledinterview',
|
||||
index=models.Index(fields=['job', 'status'], name='recruitment_job_id_f09e22_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='scheduledinterview',
|
||||
index=models.Index(fields=['interview_date', 'interview_time'], name='recruitment_intervi_7f5877_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='scheduledinterview',
|
||||
index=models.Index(fields=['candidate', 'job'], name='recruitment_candida_43d5b0_idx'),
|
||||
),
|
||||
]
|
||||
@ -823,6 +823,22 @@ def form_wizard_view(request, template_id):
|
||||
"""Display the form as a step-by-step wizard"""
|
||||
template = get_object_or_404(FormTemplate, pk=template_id, is_active=True)
|
||||
job_id = template.job.internal_job_id
|
||||
job=template.job
|
||||
is_limit_exceeded=job.is_application_limit_reached
|
||||
if is_limit_exceeded:
|
||||
messages.error(
|
||||
request,
|
||||
'Application limit reached: This job is no longer accepting new applications. Please explore other available positions.'
|
||||
)
|
||||
return redirect('job_detail_candidate',slug=job.slug)
|
||||
|
||||
if job.is_expired:
|
||||
messages.error(
|
||||
request,
|
||||
'Application deadline passed: This job is no longer accepting new applications. Please explore other available positions.'
|
||||
)
|
||||
return redirect('job_detail_candidate',slug=job.slug)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"forms/form_wizard.html",
|
||||
@ -2046,8 +2062,12 @@ def user_profile_image_update(request, pk):
|
||||
def user_detail(request, pk):
|
||||
user = get_object_or_404(User, pk=pk)
|
||||
|
||||
try:
|
||||
profile_instance = user.profile
|
||||
profile_form = ProfileImageUploadForm(instance=profile_instance)
|
||||
except:
|
||||
profile_form = ProfileImageUploadForm()
|
||||
|
||||
profile_form = ProfileImageUploadForm()
|
||||
if request.method == 'POST':
|
||||
first_name=request.POST.get('first_name')
|
||||
last_name=request.POST.get('last_name')
|
||||
@ -2175,6 +2195,25 @@ def set_staff_password(request,pk):
|
||||
return render(request,'user/staff_password_create.html',{'form':form,'user':user})
|
||||
|
||||
|
||||
@user_passes_test(is_superuser_check)
|
||||
def account_toggle_status(request,pk):
|
||||
user=get_object_or_404(User,pk=pk)
|
||||
if request.method=='POST':
|
||||
print(user.is_active)
|
||||
form=ToggleAccountForm(request.POST)
|
||||
if form.is_valid():
|
||||
if user.is_active:
|
||||
user.is_active=False
|
||||
user.save()
|
||||
messages.success(request,f'Staff with email: {user.email} deactivated successfully')
|
||||
return redirect('admin_settings')
|
||||
else:
|
||||
user.is_active=True
|
||||
user.save()
|
||||
messages.success(request,f'Staff with email: {user.email} activated successfully')
|
||||
return redirect('admin_settings')
|
||||
else:
|
||||
messages.error(f'Please correct the error below')
|
||||
|
||||
|
||||
@login_required
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user