Browse Source

Envío de correos recordatorios

main
Celestino Rey 9 months ago
parent
commit
27fe5c9437
4 changed files with 106 additions and 18 deletions
  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 View File

@ -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 View File

@ -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 View File

@ -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 View File

@ -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 %}

Loading…
Cancel
Save