Site/programmer/utils/email_notifications.py

255 lines
9.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.core.mail import send_mail, get_connection
from django.template.loader import render_to_string
from django.conf import settings
from django.utils.html import strip_tags
import logging
logger = logging.getLogger(__name__)
def send_callback_notification(callback_request):
"""
Отправляет уведомление о новой заявке на обратный звонок
"""
try:
subject = f'🚨 Новая заявка на обратный звонок от {callback_request.name}'
# HTML версия письма
html_message = render_to_string('emails/callback_notification.html', {
'callback': callback_request,
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
})
# Текстовая версия письма
plain_message = strip_tags(html_message)
# Проверяем настройки email
if not all([settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD]):
logger.error("Email settings are not configured properly")
return False
# Отправляем email
send_mail(
subject=subject,
message=plain_message,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=settings.ADMIN_EMAILS,
html_message=html_message,
fail_silently=False,
)
logger.info(f"Email notification sent successfully for callback #{callback_request.id}")
return True
except Exception as e:
logger.error(f"Error sending email notification: {e}")
return False
def send_test_email():
"""
Функция для тестирования отправки email
"""
try:
send_mail(
subject='📧 Test Email from Django',
message='This is a test email from your Django application.',
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=settings.ADMIN_EMAILS,
fail_silently=False,
)
return True
except Exception as e:
logger.error(f"Test email failed: {e}")
return False
def send_multiple_callback_notifications(callbacks):
"""
Отправляет уведомления для нескольких заявок, используя одно SMTP-соединение.
Возвращает количество успешно отправленных.
"""
if not callbacks:
return 0
connection = get_connection()
try:
connection.open()
count = 0
for callback in callbacks:
try:
subject = f'🚨 Новая заявка на обратный звонок от {callback.name}'
html_message = render_to_string('emails/callback_notification.html', {
'callback': callback,
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
})
plain_message = strip_tags(html_message)
send_mail(
subject=subject,
message=plain_message,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=settings.ADMIN_EMAILS,
html_message=html_message,
connection=connection, # используем одно соединение
fail_silently=False,
)
count += 1
except Exception as e:
logger.error(f"Error sending email for callback #{callback.id}: {e}")
connection.close()
return count
except Exception as e:
logger.error(f"Connection error: {e}")
if connection:
connection.close()
return 0
# ===== Уведомления о заказах =====
def send_order_notification(order):
"""
Отправляет уведомление о новом заказе:
- администратору (на ADMIN_EMAILS)
- клиенту (на email из заказа, если указан)
Возвращает True, если хотя бы одно письмо отправлено.
"""
try:
if not all([settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD]):
logger.error("Email settings are not configured properly")
return False
admin_sent = False
client_sent = False
# Письмо администратору
subject_admin = f'🛒 Новый заказ #{order.id} от {order.name}'
html_admin = render_to_string('products/emails/order_admin.html', {
'order': order,
'product': order.product,
'configuration': order.configuration,
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
})
plain_admin = strip_tags(html_admin)
send_mail(
subject=subject_admin,
message=plain_admin,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=settings.ADMIN_EMAILS,
html_message=html_admin,
fail_silently=False,
)
admin_sent = True
logger.info(f"Order admin notification sent for order #{order.id}")
# Письмо клиенту (если email указан)
if order.email:
subject_client = f'✅ Ваш заказ #{order.id} на {order.product.title} принят'
html_client = render_to_string('products/emails/order_client.html', {
'order': order,
'product': order.product,
'configuration': order.configuration,
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
})
plain_client = strip_tags(html_client)
send_mail(
subject=subject_client,
message=plain_client,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[order.email],
html_message=html_client,
fail_silently=False,
)
client_sent = True
logger.info(f"Order client notification sent to {order.email} for order #{order.id}")
return admin_sent or client_sent
except Exception as e:
logger.error(f"Error sending order notification for order #{order.id}: {e}")
return False
def send_multiple_order_notifications(orders):
"""
Отправляет уведомления для нескольких заказов, используя одно SMTP-соединение.
Возвращает количество успешно отправленных заказов.
"""
if not orders:
return 0
connection = get_connection()
try:
connection.open()
count = 0
for order in orders:
try:
# Администратору
subject_admin = f'🛒 Новый заказ #{order.id} от {order.name}'
html_admin = render_to_string('products/emails/order_admin.html', {
'order': order,
'product': order.product,
'configuration': order.configuration,
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
})
plain_admin = strip_tags(html_admin)
send_mail(
subject=subject_admin,
message=plain_admin,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=settings.ADMIN_EMAILS,
html_message=html_admin,
connection=connection,
fail_silently=False,
)
# Клиенту
if order.email:
subject_client = f'✅ Ваш заказ #{order.id} на {order.product.title} принят'
html_client = render_to_string('products/emails/order_client.html', {
'order': order,
'product': order.product,
'configuration': order.configuration,
'site_url': settings.ALLOWED_HOSTS[0] if settings.ALLOWED_HOSTS else 'localhost',
})
plain_client = strip_tags(html_client)
send_mail(
subject=subject_client,
message=plain_client,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[order.email],
html_message=html_client,
connection=connection,
fail_silently=False,
)
count += 1
logger.info(f"Order notifications sent for order #{order.id}")
except Exception as e:
logger.error(f"Error sending order notifications for order #{order.id}: {e}")
connection.close()
return count
except Exception as e:
logger.error(f"Connection error in send_multiple_order_notifications: {e}")
if connection:
connection.close()
return 0
def send_test_order_email():
"""Тестовая отправка письма для проверки настроек почты."""
try:
send_mail(
subject='📧 Test Order Email',
message='This is a test email for order notifications.',
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=settings.ADMIN_EMAILS,
fail_silently=False,
)
return True
except Exception as e:
logger.error(f"Test order email failed: {e}")
return False