small update

This commit is contained in:
ismail 2025-10-22 16:02:54 +03:00
parent f0d3218caa
commit ba911a60d6
8 changed files with 41 additions and 7 deletions

View File

@ -1,11 +1,12 @@
from recruitment import views
from django.conf import settings
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.conf.urls.static import static from django.conf.urls.static import static
from django.conf import settings from django.views.generic import RedirectView
from django.conf.urls.i18n import i18n_patterns # Import i18n_patterns from django.conf.urls.i18n import i18n_patterns
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
from recruitment import views
router = DefaultRouter() router = DefaultRouter()
router.register(r'jobs', views.JobPostingViewSet) router.register(r'jobs', views.JobPostingViewSet)
@ -34,7 +35,6 @@ urlpatterns = [
urlpatterns += i18n_patterns( urlpatterns += i18n_patterns(
path('', include('recruitment.urls')), path('', include('recruitment.urls')),
) )
# 2. URLs that DO have a language prefix (user-facing views) # 2. URLs that DO have a language prefix (user-facing views)
# This includes the root path (''), which is handled by 'recruitment.urls' # This includes the root path (''), which is handled by 'recruitment.urls'

View File

@ -1,5 +1,8 @@
import logging import logging
from django.db import transaction from django.db import transaction
from django_q.models import Schedule
from django_q.tasks import schedule
from django.dispatch import receiver from django.dispatch import receiver
from django_q.tasks import async_task from django_q.tasks import async_task
from django.db.models.signals import post_save from django.db.models.signals import post_save
@ -16,7 +19,31 @@ def format_job(sender, instance, created, **kwargs):
instance.pk, instance.pk,
# hook='myapp.tasks.email_sent_callback' # Optional callback # hook='myapp.tasks.email_sent_callback' # Optional callback
) )
else:
existing_schedule = Schedule.objects.filter(
func='recruitment.tasks.form_close',
args=f'[{instance.pk}]',
schedule_type=Schedule.ONCE
).first()
if instance.is_active and instance.application_deadline:
if not existing_schedule:
# Create a new schedule if one does not exist
schedule(
'recruitment.tasks.form_close',
instance.pk,
schedule_type=Schedule.ONCE,
next_run=instance.application_deadline,
repeats=-1, # Ensure the schedule is deleted after it runs
name=f'job_closing_{instance.pk}' # Add a name for easier lookup
)
elif existing_schedule.next_run != instance.application_deadline:
# Update an existing schedule's run time
existing_schedule.next_run = instance.application_deadline
existing_schedule.save()
elif existing_schedule:
# If the instance is no longer active, delete the scheduled task
existing_schedule.delete()
@receiver(post_save, sender=Candidate) @receiver(post_save, sender=Candidate)
def score_candidate_resume(sender, instance, created, **kwargs): def score_candidate_resume(sender, instance, created, **kwargs):

View File

@ -552,3 +552,10 @@ def linkedin_post_task(job_slug, access_token):
job.linkedin_post_status = f"CRITICAL_ERROR: {str(e)}" job.linkedin_post_status = f"CRITICAL_ERROR: {str(e)}"
job.save() job.save()
return False return False
def form_close(job_id):
job = get_object_or_404(JobPosting, pk=job_id)
job.is_active = False
job.template_form.is_active = False
job.save()

View File

@ -344,7 +344,7 @@
}); });
} }
form_loader(); //form_loader();
try{ try{
document.addEventListener('htmx:afterSwap', form_loader); document.addEventListener('htmx:afterSwap', form_loader);

View File

@ -824,7 +824,7 @@
}); });
try { try {
const response = await fetch(`/${state.templateId}/submit/`, { const response = await fetch(`/form/${state.templateId}/submit/`, {
method: 'POST', method: 'POST',
body: formData body: formData
// IMPORTANT: Do NOT set Content-Type header when using FormData // IMPORTANT: Do NOT set Content-Type header when using FormData

View File

@ -297,7 +297,7 @@ window.generateRandomKey = generateRandomKey;
</div> </div>
{% endblock %} {% endblock %}
{% block extra_js %} {% block customJS %}
<script> <script>
// Function to copy text to clipboard // Function to copy text to clipboard
function copyToClipboard(elementId) { function copyToClipboard(elementId) {