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): 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.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 View File

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

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

Loading…
Cancel
Save