Преглед на файлове

Envío de correos recordatorios

Celestino Rey преди 1 година
родител
ревизия
27fe5c9437
променени са 4 файла, в които са добавени 106 реда и са изтрити 18 реда
  1. 13 2
      src/eventos/forms.py
  2. 35 14
      src/eventos/views.py
  3. 56 0
      src/gestion_reservas/settings.py
  4. 2 2
      src/templates/eventos/enviar_correo_inscritos.html

+ 13 - 2
src/eventos/forms.py

@@ -21,5 +21,16 @@ class ListaEsperaForm(forms.ModelForm):
 
 
 
 
 class MensajeCorreoForm(forms.Form):
 class MensajeCorreoForm(forms.Form):
-    asunto = forms.CharField(label="Asunto", max_length=200, required=True, widget=forms.TextInput(attrs={'class': 'form-control'}))
-    mensaje = forms.CharField(label="Mensaje", widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4}), required=True)
+    asunto = forms.CharField(
+        label="Asunto",
+        max_length=200,
+        required=True,
+        widget=forms.TextInput(attrs={'class': 'form-control'})
+    )
+
+    mensaje = forms.CharField(
+        label="Mensaje",
+        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 16}),
+        required=True
+    )
+

+ 35 - 14
src/eventos/views.py

@@ -6,7 +6,13 @@ from django.conf import settings
 from django.template.loader import render_to_string
 from django.template.loader import render_to_string
 from django.utils import timezone
 from django.utils import timezone
 
 
-from django.core.mail import send_mail
+import logging
+
+from django.core.mail import send_mass_mail
+from django.core.mail import BadHeaderError
+from smtplib import SMTPException
+
+from django.http import HttpResponse
 
 
 from rest_framework.response import Response
 from rest_framework.response import Response
 from rest_framework.decorators import api_view
 from rest_framework.decorators import api_view
@@ -15,6 +21,8 @@ from .serializers import EventoSerializer, ReservaSerializer, ListaEsperaSeriali
 from .models import Evento, Reserva, ListaEspera, Noticia
 from .models import Evento, Reserva, ListaEspera, Noticia
 from .forms import ListaEsperaForm, EventoForm, MensajeCorreoForm
 from .forms import ListaEsperaForm, EventoForm, MensajeCorreoForm
 
 
+logger = logging.getLogger(__name__)
+
 
 
 @login_required
 @login_required
 def reservar_evento(request, evento_id):
 def reservar_evento(request, evento_id):
@@ -300,6 +308,7 @@ def api_detalle_noticia(request, noticia_id):
 def es_admin(user):
 def es_admin(user):
     return user.is_staff
     return user.is_staff
 
 
+
 @user_passes_test(es_admin)  # Solo administradores pueden acceder
 @user_passes_test(es_admin)  # Solo administradores pueden acceder
 def enviar_correo_inscritos(request, evento_id):
 def enviar_correo_inscritos(request, evento_id):
     evento = get_object_or_404(Evento, id=evento_id)
     evento = get_object_or_404(Evento, id=evento_id)
@@ -307,31 +316,43 @@ def enviar_correo_inscritos(request, evento_id):
 
 
     if not inscritos:
     if not inscritos:
         messages.warning(request, "No hay usuarios inscritos en este evento.")
         messages.warning(request, "No hay usuarios inscritos en este evento.")
-        return redirect('detalle_evento', evento_id=evento.id)
+        return redirect('eventos:detalle_evento', evento_id=evento.id)
 
 
     destinatarios = [reserva.usuario.email for reserva in inscritos if reserva.usuario.email]
     destinatarios = [reserva.usuario.email for reserva in inscritos if reserva.usuario.email]
 
 
     if not destinatarios:
     if not destinatarios:
         messages.warning(request, "No hay correos disponibles para los inscritos.")
         messages.warning(request, "No hay correos disponibles para los inscritos.")
-        return redirect('detalle_evento', evento_id=evento.id)
+        return redirect('eventos:detalle_evento', evento_id=evento.id)
 
 
     if request.method == "POST":
     if request.method == "POST":
         form = MensajeCorreoForm(request.POST)
         form = MensajeCorreoForm(request.POST)
         if form.is_valid():
         if form.is_valid():
-            asunto = form.cleaned_data['asunto']
-            mensaje = form.cleaned_data['mensaje']
+            asunto_usuario = form.cleaned_data['asunto']
+            mensaje_usuario = form.cleaned_data['mensaje']
+
+            asunto = f"{asunto_usuario} - {evento.nombre}"
 
 
-            send_mail(
-                asunto,
-                mensaje,
-                settings.DEFAULT_FROM_EMAIL,
-                destinatarios,
-                fail_silently=False
-            )
+            firma = "\n\n\nSaludos, \n\nPádel entre amigos"
+            mensaje = f"{mensaje_usuario}{firma}"
+
+            mensaje_comun = (asunto, mensaje, settings.DEFAULT_FROM_EMAIL, destinatarios)
+            mensaje_final = [mensaje_comun]
+
+            try:
+                send_mass_mail(mensaje_final, fail_silently=False)
+            except BadHeaderError:
+                return HttpResponse('Encabezado inválido encontrado.')
+            except SMTPException as e:
+                return HttpResponse(f'Error de SMTP: {e}')
+            except Exception as e:
+                return HttpResponse(f'Ocurrió un error: {e}')
+
+            logger.debug('Correo enviado')
 
 
             messages.success(request, f"Correo enviado a {len(destinatarios)} inscritos.")
             messages.success(request, f"Correo enviado a {len(destinatarios)} inscritos.")
-            return redirect('detalle_evento', evento_id=evento.id)
+            return redirect('eventos:detalle_evento', evento_id=evento.id)
     else:
     else:
         form = MensajeCorreoForm()
         form = MensajeCorreoForm()
 
 
-    return redirect('eventos:detalle_evento', evento_id=evento.id)
+    return render(request, 'eventos/enviar_correo_inscritos.html', {'form': form, 'evento': evento})
+

+ 56 - 0
src/gestion_reservas/settings.py

@@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/5.1/ref/settings/
 
 
 from pathlib import Path
 from pathlib import Path
 import os
 import os
+import logging
 
 
 # Build paths inside the project like this: BASE_DIR / 'subdir'.
 # Build paths inside the project like this: BASE_DIR / 'subdir'.
 BASE_DIR = Path(__file__).resolve().parent.parent
 BASE_DIR = Path(__file__).resolve().parent.parent
@@ -171,3 +172,58 @@ ADMIN_EMAIL = ''
 
 
 # El tiempo de validez del enlace para resetear la contraseña (por defecto es de 3 días)
 # El tiempo de validez del enlace para resetear la contraseña (por defecto es de 3 días)
 PASSWORD_RESET_TIMEOUT = 86400  # 1 día en segundos
 PASSWORD_RESET_TIMEOUT = 86400  # 1 día en segundos
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'formatters': {
+        'verbose': {
+            'format': '{levelname} {asctime} {module} {message}',
+            'style': '{',
+        },
+        'simple': {
+            'format': '{levelname} {message}',
+            'style': '{',
+        },
+    },
+    'handlers': {
+        'console': {
+            'level': 'DEBUG',
+            'class': 'logging.StreamHandler',
+            'formatter': 'simple',
+        },
+        'file': {
+            'level': 'DEBUG',
+            'class': 'logging.FileHandler',
+            'filename': '/dev/null',
+            'formatter': 'verbose',
+        },
+        'mail_admins': {
+            'level': 'ERROR',
+            'class': 'django.utils.log.AdminEmailHandler',
+        },
+    },
+    'loggers': {
+        'django': {
+            'handlers': ['file'],
+            'level': 'DEBUG',
+            'propagate': True,
+        },
+        'eventos': {
+            'handlers': ['console', 'file'],
+            'level': 'DEBUG',
+            'propagate': False,
+        },
+        'gestion_reservas': {
+            'handlers': ['console', 'file'],
+            'level': 'DEBUG',
+            'propagate': False,
+        },
+        'django.request': {
+            'handlers': ['mail_admins'],
+            'level': 'ERROR',
+            'propagate': False,
+        },
+    },
+}
+

+ 2 - 2
src/templates/eventos/enviar_correo_inscritos.html

@@ -2,7 +2,7 @@
 
 
 {% block content %}
 {% block content %}
 <div class="container">
 <div class="container">
-    <h2>Enviar correo a los inscritos en "{{ evento.titulo }}"</h2>
+    <h2>Enviar correo a los inscritos en "{{ evento.nombre }}"</h2>
     <form method="post">
     <form method="post">
         {% csrf_token %}
         {% csrf_token %}
         <div class="mb-3">
         <div class="mb-3">
@@ -14,7 +14,7 @@
             {{ form.mensaje }}
             {{ form.mensaje }}
         </div>
         </div>
         <button type="submit" class="btn btn-primary">📧 Enviar Correo</button>
         <button type="submit" class="btn btn-primary">📧 Enviar Correo</button>
-        <a href="{% url 'eventos:detalle_evento' evento.id %}" class="btn btn-secondary">Cancelar</a>
+        <a href="{% url 'eventos:lista_eventos' %}">Volver a la lista de eventos</a>
     </form>
     </form>
 </div>
 </div>
 {% endblock %}
 {% endblock %}