def voter_bulk_send_email(request): selected_tenant_id = request.session.get("tenant_id") tenant = get_object_or_404(Tenant, id=selected_tenant_id) campaign_settings = CampaignSettings.objects.get(tenant=tenant) if request.method == 'POST': subject = request.POST.get('subject') body = request.POST.get('body') is_html = request.POST.get("is_html") == "on" select_all_results = request.POST.get('select_all_results') == 'true' if select_all_results: voters, _ = get_filtered_voter_queryset(request, tenant, data_source='POST') voters = voters.exclude(email='') else: voter_ids = request.POST.getlist('selected_voters') voters = Voter.objects.filter(id__in=voter_ids, tenant=tenant).exclude(email='') if not voters.exists(): messages.warning(request, "No voters with email addresses selected.") return redirect('voter_advanced_search') connection = get_tenant_email_connection(campaign_settings) if not connection: messages.error(request, "SMTP settings are not configured. Please check Campaign Settings.") return redirect('voter_advanced_search') from_email = campaign_settings.email_from_address or settings.DEFAULT_FROM_EMAIL if campaign_settings.email_from_name: from_email = f"{campaign_settings.email_from_name} <{from_email}>" email_type, _ = InteractionType.objects.get_or_create(tenant=tenant, name='Email') sent_count = 0 error_count = 0 for voter in voters: try: email = EmailMessage( subject, body, from_email, [voter.email], connection=connection, ) if is_html: email.content_subtype = "html" email.send() sent_count += 1 # Log interaction Interaction.objects.create( voter=voter, type=email_type, date=timezone.now(), description=subject, notes=body ) except Exception as e: logger.error(f"Error sending bulk email to voter {voter.email}: {e}") error_count += 1 if sent_count > 0: messages.success(request, f"Successfully sent {sent_count} emails.") if error_count > 0: messages.error(request, f"Failed to send {error_count} emails.") return redirect('voter_advanced_search')