289 lines
11 KiB
Python
289 lines
11 KiB
Python
from django.contrib import admin
|
|
from django.utils.html import format_html
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from .models import (
|
|
JobPosting, Candidate, TrainingMaterial, ZoomMeeting,
|
|
FormTemplate, FormStage, FormField, FormSubmission, FieldResponse,
|
|
SharedFormTemplate, Source, HiringAgency, IntegrationLog,InterviewSchedule,Profile,JobPostingImage,MeetingComment
|
|
)
|
|
|
|
class FormFieldInline(admin.TabularInline):
|
|
model = FormField
|
|
extra = 1
|
|
ordering = ('order',)
|
|
|
|
class FormStageInline(admin.TabularInline):
|
|
model = FormStage
|
|
extra = 1
|
|
ordering = ('order',)
|
|
inlines = [FormFieldInline]
|
|
|
|
@admin.register(Source)
|
|
class SourceAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'source_type', 'ip_address', 'is_active', 'sync_status', 'created_at']
|
|
list_filter = ['source_type', 'is_active', 'sync_status', 'created_at']
|
|
search_fields = ['name', 'description']
|
|
readonly_fields = ['created_at', 'last_sync_at']
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('name', 'source_type', 'description')
|
|
}),
|
|
('Technical Details', {
|
|
'fields': ('ip_address', 'api_key', 'api_secret', 'trusted_ips')
|
|
}),
|
|
('Integration Status', {
|
|
'fields': ('is_active', 'integration_version', 'sync_status', 'last_sync_at', 'created_at')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
actions = ['activate_sources', 'deactivate_sources']
|
|
|
|
def activate_sources(self, request, queryset):
|
|
updated = queryset.update(is_active=True)
|
|
self.message_user(request, f'{updated} sources activated.')
|
|
activate_sources.short_description = 'Activate selected sources'
|
|
|
|
def deactivate_sources(self, request, queryset):
|
|
updated = queryset.update(is_active=False)
|
|
self.message_user(request, f'{updated} sources deactivated.')
|
|
deactivate_sources.short_description = 'Deactivate selected sources'
|
|
|
|
|
|
@admin.register(IntegrationLog)
|
|
class IntegrationLogAdmin(admin.ModelAdmin):
|
|
list_display = ['source', 'action', 'endpoint', 'status_code', 'ip_address', 'created_at']
|
|
list_filter = ['action', 'status_code', 'source', 'created_at']
|
|
search_fields = ['source__name', 'endpoint', 'error_message']
|
|
readonly_fields = ['source', 'action', 'endpoint', 'method', 'request_data',
|
|
'response_data', 'status_code', 'error_message', 'ip_address',
|
|
'user_agent', 'processing_time', 'created_at']
|
|
fieldsets = (
|
|
('Request Information', {
|
|
'fields': ('source', 'action', 'endpoint', 'method', 'ip_address', 'user_agent')
|
|
}),
|
|
('Data', {
|
|
'fields': ('request_data', 'response_data')
|
|
}),
|
|
('Results', {
|
|
'fields': ('status_code', 'error_message', 'processing_time', 'created_at')
|
|
}),
|
|
)
|
|
save_on_top = False
|
|
date_hierarchy = 'created_at'
|
|
|
|
|
|
@admin.register(HiringAgency)
|
|
class HiringAgencyAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'contact_person', 'email', 'phone', 'country', 'created_at']
|
|
list_filter = ['country', 'created_at']
|
|
search_fields = ['name', 'contact_person', 'email', 'phone', 'notes']
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('name', 'contact_person', 'email', 'phone', 'website')
|
|
}),
|
|
('Location Details', {
|
|
'fields': ('country', 'address')
|
|
}),
|
|
('Additional Information', {
|
|
'fields': ('notes', 'created_at', 'updated_at')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
|
|
|
|
@admin.register(JobPosting)
|
|
class JobPostingAdmin(admin.ModelAdmin):
|
|
list_display = ['internal_job_id', 'title', 'department', 'job_type', 'status', 'posted_to_linkedin', 'created_at']
|
|
list_filter = ['job_type', 'status', 'workplace_type', 'source', 'created_at']
|
|
search_fields = ['title', 'department', 'internal_job_id']
|
|
readonly_fields = ['internal_job_id', 'created_at', 'updated_at']
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('title', 'department', 'job_type', 'workplace_type', 'status')
|
|
}),
|
|
('Location', {
|
|
'fields': ('location_city', 'location_state', 'location_country')
|
|
}),
|
|
('Job Details', {
|
|
'fields': ('description', 'qualifications', 'salary_range', 'benefits')
|
|
}),
|
|
('Application Information', {
|
|
'fields': ('application_url', 'application_deadline', 'application_instructions')
|
|
}),
|
|
('Internal Tracking', {
|
|
'fields': ('internal_job_id', 'created_by', 'created_at', 'updated_at')
|
|
}),
|
|
('Integration', {
|
|
'fields': ('source', 'open_positions', 'position_number', 'reporting_to', 'start_date')
|
|
}),
|
|
('LinkedIn Integration', {
|
|
'fields': ('posted_to_linkedin', 'linkedin_post_id', 'linkedin_post_url', 'linkedin_posted_at')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
actions = ['make_published', 'make_draft', 'mark_as_closed']
|
|
|
|
def make_published(self, request, queryset):
|
|
updated = queryset.update(status='PUBLISHED')
|
|
self.message_user(request, f'{updated} job postings marked as published.')
|
|
make_published.short_description = 'Mark selected jobs as published'
|
|
|
|
def make_draft(self, request, queryset):
|
|
updated = queryset.update(status='DRAFT')
|
|
self.message_user(request, f'{updated} job postings marked as draft.')
|
|
make_draft.short_description = 'Mark selected jobs as draft'
|
|
|
|
def mark_as_closed(self, request, queryset):
|
|
updated = queryset.update(status='CLOSED')
|
|
self.message_user(request, f'{updated} job postings marked as closed.')
|
|
mark_as_closed.short_description = 'Mark selected jobs as closed'
|
|
|
|
|
|
@admin.register(Candidate)
|
|
class CandidateAdmin(admin.ModelAdmin):
|
|
list_display = ['full_name', 'job', 'email', 'phone', 'stage', 'applied','is_resume_parsed', 'created_at']
|
|
list_filter = ['stage', 'applied', 'created_at', 'job__department']
|
|
search_fields = ['first_name', 'last_name', 'email', 'phone']
|
|
readonly_fields = ['slug', 'created_at', 'updated_at']
|
|
fieldsets = (
|
|
('Personal Information', {
|
|
'fields': ('first_name', 'last_name', 'email', 'phone', 'resume')
|
|
}),
|
|
('Application Details', {
|
|
'fields': ('job', 'applied', 'stage','is_resume_parsed')
|
|
}),
|
|
('Interview Process', {
|
|
'fields': ('exam_date', 'exam_status', 'interview_date', 'interview_status', 'offer_date', 'offer_status', 'join_date')
|
|
}),
|
|
('Scoring', {
|
|
'fields': ('ai_analysis_data',)
|
|
}),
|
|
('Additional Information', {
|
|
'fields': ('submitted_by_agency', 'created_at', 'updated_at')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
actions = ['mark_as_applied', 'mark_as_not_applied']
|
|
|
|
def mark_as_applied(self, request, queryset):
|
|
updated = queryset.update(applied=True)
|
|
self.message_user(request, f'{updated} candidates marked as applied.')
|
|
mark_as_applied.short_description = 'Mark selected candidates as applied'
|
|
|
|
def mark_as_not_applied(self, request, queryset):
|
|
updated = queryset.update(applied=False)
|
|
self.message_user(request, f'{updated} candidates marked as not applied.')
|
|
mark_as_not_applied.short_description = 'Mark selected candidates as not applied'
|
|
|
|
|
|
@admin.register(TrainingMaterial)
|
|
class TrainingMaterialAdmin(admin.ModelAdmin):
|
|
list_display = ['title', 'created_by', 'created_at']
|
|
list_filter = ['created_at']
|
|
search_fields = ['title', 'content']
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('title', 'content')
|
|
}),
|
|
('Media', {
|
|
'fields': ('video_link', 'file')
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('created_by', 'created_at', 'updated_at')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
|
|
|
|
@admin.register(ZoomMeeting)
|
|
class ZoomMeetingAdmin(admin.ModelAdmin):
|
|
list_display = ['topic', 'meeting_id', 'start_time', 'duration', 'created_at']
|
|
list_filter = ['timezone', 'created_at']
|
|
search_fields = ['topic', 'meeting_id']
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
fieldsets = (
|
|
('Meeting Details', {
|
|
'fields': ('topic', 'meeting_id', 'start_time', 'duration', 'timezone','status')
|
|
}),
|
|
('Meeting Settings', {
|
|
'fields': ('participant_video', 'join_before_host', 'mute_upon_entry', 'waiting_room')
|
|
}),
|
|
('Access', {
|
|
'fields': ('join_url',)
|
|
}),
|
|
('System Response', {
|
|
'fields': ('zoom_gateway_response', 'created_at', 'updated_at')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
|
|
|
|
@admin.register(MeetingComment)
|
|
class MeetingCommentAdmin(admin.ModelAdmin):
|
|
list_display = ['meeting', 'author', 'created_at', 'updated_at']
|
|
list_filter = ['created_at', 'author', 'meeting']
|
|
search_fields = ['content', 'meeting__topic', 'author__username']
|
|
readonly_fields = ['created_at', 'updated_at', 'slug']
|
|
fieldsets = (
|
|
('Meeting Information', {
|
|
'fields': ('meeting', 'author')
|
|
}),
|
|
('Comment Content', {
|
|
'fields': ('content',)
|
|
}),
|
|
('Timestamps', {
|
|
'fields': ('created_at', 'updated_at', 'slug')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
|
|
|
|
@admin.register(FormTemplate)
|
|
class FormTemplateAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'created_by', 'created_at', 'is_active']
|
|
list_filter = ['is_active', 'created_at']
|
|
search_fields = ['name', 'description']
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
inlines = [FormStageInline]
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('name', 'description', 'created_by', 'is_active')
|
|
}),
|
|
('Timeline', {
|
|
'fields': ('created_at', 'updated_at')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
|
|
|
|
@admin.register(FormSubmission)
|
|
class FormSubmissionAdmin(admin.ModelAdmin):
|
|
list_display = ['template', 'applicant_name', 'submitted_at', 'submitted_by']
|
|
list_filter = ['submitted_at', 'template']
|
|
search_fields = ['applicant_name', 'applicant_email']
|
|
readonly_fields = ['submitted_at']
|
|
fieldsets = (
|
|
('Submission Information', {
|
|
'fields': ('template', 'submitted_by', 'submitted_at')
|
|
}),
|
|
('Applicant Information', {
|
|
'fields': ('applicant_name', 'applicant_email')
|
|
}),
|
|
)
|
|
save_on_top = True
|
|
|
|
|
|
# Register other models
|
|
admin.site.register(FormStage)
|
|
admin.site.register(FormField)
|
|
admin.site.register(FieldResponse)
|
|
admin.site.register(InterviewSchedule)
|
|
admin.site.register(Profile)
|
|
# admin.site.register(HiringAgency)
|
|
|
|
|
|
admin.site.register(JobPostingImage)
|