Browse Source

Envío de correos recordatorios

Celestino Rey 1 năm trước cách đây
mục cha
commit
27fe5c9437

+ 13 - 2
src/eventos/forms.py

@@ -21,5 +21,16 @@ class ListaEsperaForm(forms.ModelForm):
 
 
 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.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.decorators import api_view
@@ -15,6 +21,8 @@ from .serializers import EventoSerializer, ReservaSerializer, ListaEsperaSeriali
 from .models import Evento, Reserva, ListaEspera, Noticia
 from .forms import ListaEsperaForm, EventoForm, MensajeCorreoForm
 
+logger = logging.getLogger(__name__)
+
 
 @login_required
 def reservar_evento(request, evento_id):
@@ -300,6 +308,7 @@ def api_detalle_noticia(request, noticia_id):
 def es_admin(user):
     return user.is_staff
 
+
 @user_passes_test(es_admin)  # Solo administradores pueden acceder
 def enviar_correo_inscritos(request, 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:
         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]
 
     if not destinatarios:
         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":
         form = MensajeCorreoForm(request.POST)
         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.")
-            return redirect('detalle_evento', evento_id=evento.id)
+            return redirect('eventos:detalle_evento', evento_id=evento.id)
     else:
         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
 import os
+import logging
 
 # Build paths inside the project like this: BASE_DIR / 'subdir'.
 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)
 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 %}
 <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">
         {% csrf_token %}
         <div class="mb-3">
@@ -14,7 +14,7 @@
             {{ form.mensaje }}
         </div>
         <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>
 </div>
 {% endblock %}