updated the messages creation

This commit is contained in:
Faheed 2025-11-23 13:14:36 +03:00
parent 8a0f715145
commit f3f60d4fc5
6 changed files with 109 additions and 64 deletions

View File

@ -0,0 +1,19 @@
# Generated by Django 5.2.7 on 2025-11-23 09:22
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('recruitment', '0003_jobposting_cv_zip_file_jobposting_zip_created'),
]
operations = [
migrations.AlterField(
model_name='interviewschedule',
name='template_location',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='schedule_templates', to='recruitment.interviewlocation', verbose_name='Location Template (Zoom/Onsite)'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 5.2.7 on 2025-11-23 09:41
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('recruitment', '0004_alter_interviewschedule_template_location'),
]
operations = [
migrations.AlterField(
model_name='interviewschedule',
name='template_location',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='schedule_templates', to='recruitment.interviewlocation', verbose_name='Location Template (Zoom/Onsite)'),
),
]

View File

@ -1162,6 +1162,9 @@ class OnsiteLocationDetails(InterviewLocation):
verbose_name_plural = _("Onsite Location Details")
# --- 2. Scheduling Models ---
class InterviewSchedule(Base):

View File

@ -761,6 +761,7 @@ from django.utils.html import strip_tags
def _task_send_individual_email(subject, body_message, recipient, attachments,sender,job):
"""Internal helper to create and send a single email."""
from_email = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@kaauh.edu.sa')
is_html = '<' in body_message and '>' in body_message
@ -780,7 +781,8 @@ def _task_send_individual_email(subject, body_message, recipient, attachments,se
try:
result=email_obj.send(fail_silently=False)
if result==1:
if result==1 and sender and job: # job is none when email sent after message creation
try:
user=get_object_or_404(User,email=recipient)
new_message = Message.objects.create(
@ -798,7 +800,7 @@ def _task_send_individual_email(subject, body_message, recipient, attachments,se
else:
logger.error("fialed to send email")
logger.error("failed to send email")
except Exception as e:

View File

@ -4674,55 +4674,40 @@ def message_create(request):
message.sender = request.user
message.save()
# Send email if message_type is 'email' and recipient has email
if message.message_type == 'email' and message.recipient and message.recipient.email:
if message.recipient and message.recipient.email:
try:
from .email_service import send_bulk_email
email_result = send_bulk_email(
email_result = async_task('recruitment.tasks._task_send_individual_email',
subject=message.subject,
message=message.content,
recipient_list=[message.recipient.email],
request=request,
body_message=message.content,
recipient=message.recipient.email,
attachments=None,
async_task_=True,
from_interview=False
sender=False,
job=False
)
if email_result["success"]:
message.is_email_sent = True
message.email_address = message.recipient.email
message.save(update_fields=['is_email_sent', 'email_address'])
if email_result:
messages.success(request, "Message sent successfully via email!")
else:
messages.warning(request, f"Message saved but email failed: {email_result.get('message', 'Unknown error')}")
messages.warning(request, f"email failed: {email_result.get('message', 'Unknown error')}")
except Exception as e:
messages.warning(request, f"Message saved but email sending failed: {str(e)}")
else:
messages.success(request, "Message sent successfully!")
["recipient", "job", "subject", "content", "message_type"]
recipient_email = form.cleaned_data['recipient'].email # Assuming recipient is a User or Model with an 'email' field
subject = form.cleaned_data['subject']
custom_message = form.cleaned_data['content']
job_id = form.cleaned_data['job'].id if 'job' in form.cleaned_data and form.cleaned_data['job'] else None
sender_user_id = request.user.id
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
sender_user_id=sender_user_id,
job_id=job_id,
hook='recruitment.tasks.email_success_hook')
logger.info(f"{task_id} queued.")
return redirect("message_list")
else:
messages.error(request, "Please correct the errors below.")
else:
form = MessageForm(request.user)
context = {
@ -4759,27 +4744,21 @@ def message_reply(request, message_id):
message.save()
# Send email if message_type is 'email' and recipient has email
if message.message_type == 'email' and message.recipient and message.recipient.email:
if message.recipient and message.recipient.email:
try:
from .email_service import send_bulk_email
email_result = send_bulk_email(
email_result = async_task('recruitment.tasks._task_send_individual_email',
subject=message.subject,
message=message.content,
recipient_list=[message.recipient.email],
request=request,
body_message=message.content,
recipient=message.recipient.email,
attachments=None,
async_task_=True,
from_interview=False
sender=False,
job=False
)
if email_result["success"]:
message.is_email_sent = True
message.email_address = message.recipient.email
message.save(update_fields=['is_email_sent', 'email_address'])
messages.success(request, "Reply sent successfully via email!")
if email_result:
messages.success(request, "Message sent successfully via email!")
else:
messages.warning(request, f"Reply saved but email failed: {email_result.get('message', 'Unknown error')}")
messages.warning(request, f"email failed: {email_result.get('message', 'Unknown error')}")
except Exception as e:
messages.warning(request, f"Reply saved but email sending failed: {str(e)}")
@ -5763,15 +5742,15 @@ def send_interview_email(request, slug):
return redirect("meeting_details", slug=meeting.slug)
# def schedule_interview_location_form(request,slug):
# schedule=get_object_or_404(InterviewSchedule,slug=slug)
# if request.method=='POST':
# form=InterviewScheduleLocationForm(request.POST,instance=schedule)
# form.save()
# return redirect('list_meetings')
# else:
# form=InterviewScheduleLocationForm(instance=schedule)
# return render(request,'interviews/schedule_interview_location_form.html',{'form':form,'schedule':schedule})
def schedule_interview_location_form(request,slug):
schedule=get_object_or_404(InterviewSchedule,slug=slug)
if request.method=='POST':
form=InterviewScheduleLocationForm(request.POST,instance=schedule)
form.save()
return redirect('list_meetings')
else:
form=InterviewScheduleLocationForm(instance=schedule)
return render(request,'interviews/schedule_interview_location_form.html',{'form':form,'schedule':schedule})
class MeetingListView(ListView):
@ -5783,6 +5762,7 @@ class MeetingListView(ListView):
context_object_name = "meetings"
paginate_by = 100
def get_queryset(self):
# Start with a base queryset, ensuring an InterviewLocation link exists.
queryset = super().get_queryset().filter(interview_location__isnull=False).select_related(
@ -5794,6 +5774,7 @@ class MeetingListView(ListView):
'interview_location__zoommeetingdetails',
'interview_location__onsitelocationdetails',
)
# Note: Printing the queryset here can consume memory for large sets.
# Get filters from GET request
@ -5807,11 +5788,10 @@ class MeetingListView(ListView):
if type_filter:
# Use .title() to handle case variations from URL (e.g., 'remote' -> 'Remote')
normalized_type = type_filter.title()
print(normalized_type)
# Assuming InterviewLocation.LocationType is accessible/defined
if normalized_type in ['Remote', 'Onsite']:
queryset = queryset.filter(interview_location__location_type=normalized_type)
print(queryset)
# 3. Search by Topic (stored on InterviewLocation)
if search_query:
@ -5886,6 +5866,28 @@ class MeetingListView(ListView):
return context
# class MeetingListView(ListView):
# """
# A unified view to list both Remote and Onsite Scheduled Interviews.
# """
# model = InterviewLocation
# template_name = "meetings/list_meetings.html"
# context_object_name = "meetings"
# def get_queryset(self):
# # Start with a base queryset, ensuring an InterviewLocation link exists.
# queryset = super().get_queryset().prefetch_related(
# 'zoommeetingdetails',
# 'onsitelocationdetails',
# )
# print(queryset)
# return queryset
def reschedule_onsite_meeting(request, slug, candidate_id, meeting_id):
"""Handles the rescheduling of an Onsite Interview (updates OnsiteLocationDetails)."""
job = get_object_or_404(JobPosting, slug=slug)

View File

@ -499,7 +499,7 @@
</h5>
<p class="text-muted small mb-0">
<i class="fas fa-calendar-alt me-1"></i>
{% trans "Applied" %}: {{ application.applied_date|date:"d M Y" }}
{% trans "Applied" %}: {{ application.created_at|date:"d M Y" }}
</p>
</div>
</div>