diff --git a/recruitment/email_service.py b/recruitment/email_service.py index 750bf12..19d68a5 100644 --- a/recruitment/email_service.py +++ b/recruitment/email_service.py @@ -242,7 +242,7 @@ def send_bulk_email(subject, message, recipient_list, request=None, attachments= Send bulk email to multiple recipients with HTML support and attachments, supporting synchronous or asynchronous dispatch. """ - + # --- 1. Categorization and Custom Message Preparation (CORRECTED) --- if not from_interview: @@ -308,19 +308,19 @@ def send_bulk_email(subject, message, recipient_list, request=None, attachments= sender_user_id=request.user.id if request and hasattr(request, 'user') and request.user.is_authenticated else None if not from_interview: # Loop through ALL final customized sends - for recipient_email, custom_message in customized_sends: - task_id = async_task( - 'recruitment.tasks.send_bulk_email_task', - subject, - custom_message, # Pass the custom message - [recipient_email], # Pass the specific recipient as a list of one - processed_attachments, - sender_user_id, - job_id, - hook='recruitment.tasks.email_success_hook', - - ) - task_ids.append(task_id) + + + task_id = async_task( + 'recruitment.tasks.send_bulk_email_task', + subject, + customized_sends, + processed_attachments, + sender_user_id, + job_id, + hook='recruitment.tasks.email_success_hook', + + ) + task_ids.append(task_id) logger.info(f"{len(task_ids)} tasks ({total_recipients} emails) queued.") diff --git a/recruitment/forms.py b/recruitment/forms.py index a28b552..16ea93d 100644 --- a/recruitment/forms.py +++ b/recruitment/forms.py @@ -81,7 +81,9 @@ class SourceForm(forms.ModelForm): } ), "ip_address": forms.TextInput( - attrs={"class": "form-control", "placeholder": "192.168.1.100"} + attrs={"class": "form-control", "placeholder": "192.168.1.100", + "required":True}, + ), "trusted_ips":forms.TextInput( attrs={"class": "form-control", "placeholder": "192.168.1.100","required": False} @@ -118,6 +120,13 @@ class SourceForm(forms.ModelForm): if Source.objects.filter(name=name).exclude(pk=instance.pk).exists(): raise ValidationError("A source with this name already exists.") return name + def clean_ip_address(self): + ip_address=self.cleaned_data.get('ip_address') + if not ip_address: + raise ValidationError(_("Ip address should not be empty")) + return ip_address + + class SourceAdvancedForm(forms.ModelForm): @@ -1063,6 +1072,7 @@ class HiringAgencyForm(forms.ModelForm): self.helper.form_class = "form-horizontal" self.helper.label_class = "col-md-3" self.helper.field_class = "col-md-9" + self.fields['email'].required=True self.helper.layout = Layout( Field("name", css_class="form-control"), @@ -1113,7 +1123,7 @@ class HiringAgencyForm(forms.ModelForm): email = email.lower().strip() if not instance.pk: # Creating new instance print("created ....") - if HiringAgency.objects.filter(email=email).exists(): + if HiringAgency.objects.filter(email=email).exists() or User.objects.filter(email=email): raise ValidationError("An agency with this email already exists.") else: # Editing existing instance if ( diff --git a/recruitment/tasks.py b/recruitment/tasks.py index 23bbf0c..20aec41 100644 --- a/recruitment/tasks.py +++ b/recruitment/tasks.py @@ -1022,31 +1022,33 @@ def _task_send_individual_email(subject, body_message, recipient, attachments,se logger.info(f"Stored sent message ID {new_message.id} in DB.") except Exception as e: logger.error(f"Email sent to {recipient}, but failed to store in DB: {str(e)}") - + return result == 1 except Exception as e: logger.error(f"Failed to send email to {recipient}: {str(e)}", exc_info=True) -def send_bulk_email_task(subject, message, recipient_list,attachments=None,sender_user_id=None,job_id=None, hook='recruitment.tasks.email_success_hook'): +def send_bulk_email_task(subject, customized_sends,attachments=None,sender_user_id=None,job_id=None, hook='recruitment.tasks.email_success_hook'): """ Django-Q background task to send pre-formatted email to a list of recipients., Receives arguments directly from the async_task call. """ - logger.info(f"Starting bulk email task for {len(recipient_list)} recipients") + print("jhjmfhsdjhfksjhdkfjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjh") + logger.info(f"Starting bulk email task for {len(customized_sends)} recipients") successful_sends = 0 - total_recipients = len(recipient_list) + total_recipients = len(customized_sends) - if not recipient_list: + if not customized_sends: return {'success': False, 'error': 'No recipients provided to task.'} sender=get_object_or_404(User,pk=sender_user_id) job=get_object_or_404(JobPosting,pk=job_id) + # Since the async caller sends one task per recipient, total_recipients should be 1. - for recipient in recipient_list: + for recipient_email, custom_message in customized_sends: # The 'message' is the custom message specific to this recipient. - r=_task_send_individual_email(subject, message, recipient, attachments,sender,job) - print(f"Email send result for {recipient}: {r}") + r=_task_send_individual_email(subject, custom_message, recipient_email, attachments,sender,job) + print(f"Email send result for {recipient_email}: {r}") if r: successful_sends += 1 print(f"successful_sends: {successful_sends} out of {total_recipients}") diff --git a/recruitment/views.py b/recruitment/views.py index 31bad6f..ef30ae3 100644 --- a/recruitment/views.py +++ b/recruitment/views.py @@ -6051,18 +6051,24 @@ def interview_list(request): # Get filter parameters status_filter = request.GET.get('status', '') + interview_type=request.GET.get('type') job_filter = request.GET.get('job', '') - search_query = request.GET.get('q', '') - + print(job_filter) + search_query = request.GET.get('search', '') + jobs=JobPosting.objects.filter(status='ACTIVE') + # Apply filters + if interview_type: + interviews=interviews.filter(interview__location_type=interview_type) if status_filter: interviews = interviews.filter(status=status_filter) if job_filter: - interviews = interviews.filter(job__title__icontains=job_filter) + interviews = interviews.filter(job__slug=job_filter) if search_query: interviews = interviews.filter( Q(application__person__first_name__icontains=search_query) | Q(application__person__last_name__icontains=search_query) | + Q(application__person__email=search_query)| Q(job__title__icontains=search_query) ) @@ -6077,6 +6083,7 @@ def interview_list(request): 'job_filter': job_filter, 'search_query': search_query, 'interviews': interviews, + 'jobs':jobs } return render(request, 'interviews/interview_list.html', context) @@ -6090,7 +6097,10 @@ def interview_detail(request, slug): reschedule_form = ScheduledInterviewForm() - reschedule_form.initial['topic'] = interview.interview.topic + try: + reschedule_form.initial['topic'] = interview.interview.topic + except Exception as e: + print(e) meeting=interview.interview context = { 'interview': interview, diff --git a/templates/interviews/interview_detail.html b/templates/interviews/interview_detail.html index c3c455e..8937a07 100644 --- a/templates/interviews/interview_detail.html +++ b/templates/interviews/interview_detail.html @@ -246,13 +246,13 @@ {% trans "Download Resume" %} {% endif %} - + {% endcomment %} diff --git a/templates/interviews/interview_list.html b/templates/interviews/interview_list.html index 8a0ee1c..03978e7 100644 --- a/templates/interviews/interview_list.html +++ b/templates/interviews/interview_list.html @@ -187,7 +187,7 @@