From f45e9b75c43fb746ddc80dc4b38e356cee8e88fa Mon Sep 17 00:00:00 2001 From: ismail Date: Sun, 30 Nov 2025 14:08:55 +0300 Subject: [PATCH] small update --- recruitment/urls.py | 7 +- recruitment/views.py | 114 +++++------------- .../interviews/interview_create_onsite.html | 78 +----------- .../interviews/interview_create_remote.html | 8 +- .../interview_create_type_selection.html | 8 +- templates/interviews/interview_detail.html | 7 +- .../applications_interview_view.html | 14 +-- 7 files changed, 51 insertions(+), 185 deletions(-) diff --git a/recruitment/urls.py b/recruitment/urls.py index 83a877d..4c50725 100644 --- a/recruitment/urls.py +++ b/recruitment/urls.py @@ -572,11 +572,12 @@ urlpatterns = [ path('interviews/', views.interview_list, name='interview_list'), path('interviews//', views.interview_detail, name='interview_detail'), path('interviews//update_interview_status', views.update_interview_status, name='update_interview_status'), + path('interviews//cancel_interview_for_application', views.cancel_interview_for_application, name='cancel_interview_for_application'), # Interview Creation URLs - path('interviews/create//', views.interview_create_type_selection, name='interview_create_type_selection'), - path('interviews/create//remote/', views.interview_create_remote, name='interview_create_remote'), - path('interviews/create//onsite/', views.interview_create_onsite, name='interview_create_onsite'), + path('interviews/create//', views.interview_create_type_selection, name='interview_create_type_selection'), + path('interviews/create//remote/', views.interview_create_remote, name='interview_create_remote'), + path('interviews/create//onsite/', views.interview_create_onsite, name='interview_create_onsite'), path('interviews//get_interview_list', views.get_interview_list, name='get_interview_list'), # # --- SCHEDULED INTERVIEW URLS (New Centralized Management) --- diff --git a/recruitment/views.py b/recruitment/views.py index f53a2c6..325d45b 100644 --- a/recruitment/views.py +++ b/recruitment/views.py @@ -5184,30 +5184,21 @@ def portal_logout(request): # Interview Creation Views @staff_user_required -def interview_create_type_selection(request, candidate_slug): - """Show interview type selection page for a candidate""" - candidate = get_object_or_404(Application, slug=candidate_slug) - # Validate candidate is in Interview stage - # if candidate.stage != 'Interview': - # messages.error(request, f"Candidate {candidate.name} is not in Interview stage.") - # return redirect('candidate_interview_view', slug=candidate.job.slug) +def interview_create_type_selection(request, application_slug): + """Show interview type selection page for a application""" + application = get_object_or_404(Application, slug=application_slug) context = { - 'candidate': candidate, - 'job': candidate.job, + 'application': application, + 'job': application.job, } return render(request, 'interviews/interview_create_type_selection.html', context) @staff_user_required -def interview_create_remote(request, candidate_slug): +def interview_create_remote(request, application_slug): """Create remote interview for a candidate""" - application = get_object_or_404(Application, slug=candidate_slug) - - # Validate candidate is in Interview stage - # if candidate.stage != 'Interview': - # messages.error(request, f"Candidate {candidate.name} is not in Interview stage.") - # return redirect('candidate_interview_view', slug=candidate.job.slug) + application = get_object_or_404(Application, slug=application_slug) if request.method == 'POST': form = RemoteInterviewForm(request.POST) @@ -5220,41 +5211,16 @@ def interview_create_remote(request, candidate_slug): "recruitment.tasks.create_interview_and_meeting", application.pk, application.job.pk, schedule.pk, schedule.interview_date,schedule.interview_time, form.cleaned_data['duration'] ) - # interview.interview_type = 'REMOTE' - # interview.status = 'SCHEDULED' - # interview.save() - - # Create ZoomMeetingDetails record - # from .models import ZoomMeetingDetails - # zoom_meeting = ZoomMeetingDetails.objects.create( - # topic=form.cleaned_data['topic'], - # start_time=timezone.make_aware( - # timezone.datetime.combine( - # form.cleaned_data['interview_date'], - # form.cleaned_data['interview_time'] - # ), - # timezone.get_current_timezone() - # ), - # duration=form.cleaned_data['duration'], - # meeting_id=f"KAUH-{interview.id}-{timezone.now().timestamp()}", - # join_url=f"https://zoom.us/j/{interview.id}", - # password=secrets.token_urlsafe(16), - # status='scheduled' - # ) - - # Link Zoom meeting to interview - # interview.interview_location = zoom_meeting - # interview.save() messages.success(request, f"Remote interview scheduled for {application.name}") - return redirect('interview_list') + return redirect('interview_detail', slug=schedule.slug) except Exception as e: messages.error(request, f"Error creating remote interview: {str(e)}") form = RemoteInterviewForm() form.initial['topic'] = f"Interview for {application.job.title} - {application.name}" context = { - 'candidate': application, + 'application': application, 'job': application.job, 'form': form, } @@ -5262,14 +5228,9 @@ def interview_create_remote(request, candidate_slug): @staff_user_required -def interview_create_onsite(request, candidate_slug): +def interview_create_onsite(request, application_slug): """Create onsite interview for a candidate""" - candidate = get_object_or_404(Application, slug=candidate_slug) - - # Validate candidate is in Interview stage - # if candidate.stage != 'Interview': - # messages.error(request, f"Candidate {candidate.name} is not in Interview stage.") - # return redirect('candidate_interview_view', slug=candidate.job.slug) + application = get_object_or_404(Application, slug=application_slug) if request.method == 'POST': from .models import Interview @@ -5283,48 +5244,22 @@ def interview_create_onsite(request, candidate_slug): physical_address=form.cleaned_data["physical_address"], duration=form.cleaned_data["duration"],location_type="Onsite",status="SCHEDULED") - schedule = ScheduledInterview.objects.create(application=candidate,job=candidate.job,interview=interview,interview_date=form.cleaned_data["interview_date"],interview_time=form.cleaned_data["interview_time"]) - # Create ScheduledInterview record - # interview = form.save(commit=False) - # interview.interview_type = 'ONSITE' - # interview.status = 'SCHEDULED' - # interview.save() + schedule = ScheduledInterview.objects.create(application=application,job=application.job,interview=interview,interview_date=form.cleaned_data["interview_date"],interview_time=form.cleaned_data["interview_time"]) - # Create OnsiteLocationDetails record - # from .models import OnsiteLocationDetails - # onsite_location = OnsiteLocationDetails.objects.create( - # topic=form.cleaned_data['topic'], - # start_time=timezone.make_aware( - # timezone.datetime.combine( - # form.cleaned_data['interview_date'], - # form.cleaned_data['interview_time'] - # ), - # timezone.get_current_timezone() - # ), - # duration=form.cleaned_data['duration'], - # physical_address=form.cleaned_data['physical_address'], - # room_number=form.cleaned_data.get('room_number', ''), - # location_type='ONSITE', - # status='scheduled' - # ) - - # # Link onsite location to interview - # interview.interview_location = onsite_location - # interview.save() - - messages.success(request, f"Onsite interview scheduled for {candidate.name}") + messages.success(request, f"Onsite interview scheduled for {application.name}") return redirect('interview_detail', slug=schedule.slug) except Exception as e: messages.error(request, f"Error creating onsite interview: {str(e)}") else: # Pre-populate topic - form.initial['topic'] = f"Interview for {candidate.job.title} - {candidate.name}" + form.initial['topic'] = f"Interview for {application.job.title} - {application.name}" form = OnsiteInterviewForm() + form.initial['topic'] = f"Interview for {application.job.title} - {application.name}" context = { - 'candidate': candidate, - 'job': candidate.job, + 'application': application, + 'job': application.job, 'form': form, } return render(request, 'interviews/interview_create_onsite.html', context) @@ -5350,6 +5285,21 @@ def update_interview_status(request,slug): messages.success(request, "Interview status updated successfully.") return redirect('interview_detail', slug=slug) +@require_POST +def cancel_interview_for_application(request,slug): + scheduled_interview = get_object_or_404(ScheduledInterview, slug=slug) + if request.method == 'POST': + if scheduled_interview.interview_type == 'REMOTE': + result = delete_zoom_meeting(scheduled_interview.interview.meeting_id) + if result["status"] != "success": + messages.error(request, f"Error cancelling Zoom meeting: {result.get('message', 'Unknown error')}") + return redirect('interview_detail', slug=slug) + + scheduled_interview.delete() + messages.success(request, "Interview cancelled successfully.") + return redirect('interview_list') + + @login_required def agency_access_link_deactivate(request, slug): """Deactivate an agency access link""" diff --git a/templates/interviews/interview_create_onsite.html b/templates/interviews/interview_create_onsite.html index 441ac15..61188a6 100644 --- a/templates/interviews/interview_create_onsite.html +++ b/templates/interviews/interview_create_onsite.html @@ -10,9 +10,9 @@

- Create Onsite Interview for {{ candidate.name }} + Create Onsite Interview for {{ application.name }}

- Back to Candidate List @@ -20,7 +20,7 @@

- Schedule an onsite interview for {{ candidate.name }} + Schedule an onsite interview for {{ application.name }} for the position of {{ job.title }}.

@@ -33,7 +33,7 @@ {% endfor %} {% endif %} -
+ {% csrf_token %}
@@ -99,36 +99,8 @@ {% endif %}
- - {% comment %}
-
- - {{ form.interviewer }} - {% if form.interviewer.errors %} -
- {{ form.interviewer.errors }} -
- {% endif %} -
-
{% endcomment %} - {% comment %}
- - {{ form.topic }} - {% if form.topic.errors %} -
- {{ form.topic.errors }} -
- {% endif %} -
{% endcomment %} -
- {% comment %}
-
- - {{ form.floor_number }} - {% if form.floor_number.errors %} -
- {{ form.floor_number.errors }} -
- {% endif %} -
-
{% endcomment %} - {% comment %} {% endcomment %} - - {% comment %}
- - {{ form.parking_info }} - {% if form.parking_info.errors %} -
- {{ form.parking_info.errors }} -
- {% endif %} -
{% endcomment %} - - {% comment %}
- - {{ form.notes }} - {% if form.notes.errors %} -
- {{ form.notes.errors }} -
- {% endif %} -
{% endcomment %} -