You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

363 lines
13 KiB

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib import messages
from django.core.mail import EmailMultiAlternatives
from django.conf import settings
from django.template.loader import render_to_string
from django.utils import timezone
import logging
from django.core.mail import send_mail
from django.core.mail import send_mass_mail
from django.core.mail import BadHeaderError, SMTPException
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .serializers import EventoSerializer, ReservaSerializer, ListaEsperaSerializer, NoticiaSerializer
from django.core.mail import BadHeaderError, SMTPException
from django.http import HttpResponse
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):
evento = get_object_or_404(Evento, id=evento_id)
# Verificar si el usuario ya tiene una reserva para este evento
if Reserva.objects.filter(evento=evento, usuario=request.user).exists():
messages.error(request, 'Ya tienes una reserva para este evento.')
return redirect('eventos:lista_eventos')
# Verificar si quedan plazas disponibles
if evento.plazas_restantes() > 0:
Reserva.objects.create(evento=evento, usuario=request.user)
# Enviar un correo con la información del evento
asunto = f'Confirmación de Reserva para {evento.nombre}'
from_email = settings.DEFAULT_FROM_EMAIL
to_email = request.user.email
cc_email = [settings.ADMIN_EMAIL]
texto = f'Hola {request.user.nombre},\n\n' \
f'Te has inscrito correctamente en el evento "{evento.nombre}".\n' \
f'Detalles del evento:\n' \
f'Nombre: {evento.nombre}\n' \
f'Descripción: {evento.descripcion}\n' \
f'Fecha: {evento.fecha.strftime("%d/%b/%y")} a las {evento.hora}\n' \
f'\n¡Gracias por inscribirte!\n\n'
html_content = render_to_string('emails/confirmacion_reserva.html', {'evento': evento, 'usuario': request.user})
# Enviar el correo con el administrador en copia
msg = EmailMultiAlternatives(asunto, texto, from_email, [to_email], cc=cc_email)
msg.attach_alternative(html_content, "text/html")
msg.send()
# Aquí hay que mirar si quedan más de n plazas.
# n es un numero aleatorio entre 2 y el total de plazas
# si es así, y ya hay añadir a dos participantes.
messages.success(request,
f'Reserva realizada para el evento {evento.nombre}.')
else:
messages.error(request, 'Lo sentimos, no quedan plazas disponibles.')
return redirect('eventos:lista_eventos')
@user_passes_test(lambda u: u.is_staff)
def publicar_evento(request, evento_id):
evento = get_object_or_404(Evento, id=evento_id)
if not evento.publicado:
evento.publicado = True
evento.save()
messages.success(request, 'El evento %s ha sido publicado' % evento.nombre)
else:
messages.info(request, 'El evento %s ya está publicado' % evento.nombre)
return redirect('eventos:detalle_evento', evento_id=evento_id)
@login_required
def lista_eventos(request):
# anno_actual = timezone.now().year
# Solo mostrar los eventos publicados a los usuarios normales
if request.user.is_staff:
eventos = Evento.objects.all().order_by('-fecha', '-hora')
else:
eventos = Evento.objects.filter(publicado=True).order_by('-fecha', '-hora')
# eventos = Evento.objects.filter(publicado=True, fecha__year=anno_actual) # Los usuarios ven solo eventos publicados y del año en curso
# Crear un diccionario que mapea cada evento con un booleano indicando si el usuario ya ha reservado
eventos_con_reserva = []
for evento in eventos:
inscrito = Reserva.objects.filter(evento=evento, usuario=request.user).exists() if request.user.is_authenticated else False
if ListaEspera.objects.filter(evento=evento, usuario=request.user).exists():
en_espera = True
else:
en_espera = False
eventos_con_reserva.append({
'evento': evento,
'inscrito': inscrito,
'id': evento.id,
'nombre': evento.nombre,
'fecha': evento.fecha,
'hora': evento.hora,
'plazas_disponibles': evento.plazas_disponibles,
'plazas_restantes': evento.plazas_restantes,
'en_espera': en_espera,
'usuario': request.user,
'publicado': evento.publicado,
'url_imagen': evento.url_imagen
})
return render(request, 'eventos/lista_eventos.html', {'eventos_con_reserva': eventos_con_reserva})
def detalle_noticia(request, noticia_id):
noticia = get_object_or_404(Noticia, id=noticia_id, publicado=True)
return render(request, 'detalle_noticia.html', {'noticia': noticia})
def ayuda(request):
return render(request, 'eventos/help.html')
@login_required
def detalle_evento(request, evento_id):
el_evento = []
evento = get_object_or_404(Evento, pk=evento_id)
reservas = Reserva.objects.filter(evento=evento_id)
inscrito = Reserva.objects.filter(evento=evento, usuario=request.user).exists() if request.user.is_authenticated else False
if ListaEspera.objects.filter(evento=evento, usuario=request.user).exists():
en_espera = True
else:
en_espera = False
lista_espera = ListaEspera.objects.filter(evento=evento_id)
el_evento.append(
{
'evento': evento,
'inscrito': inscrito,
'id': evento.id,
'nombre': evento.nombre,
'descripcion': evento.descripcion,
'fecha': evento.fecha,
'plazas_disponibles': evento.plazas_disponibles,
'plazas_restantes': evento.plazas_restantes,
'en_espera': en_espera,
'usuario': request.user,
'publicado': evento.publicado,
'url_imagen': evento.url_imagen
}
)
return render(request, 'eventos/detalle_evento.html', {'eventos': el_evento, 'reservas': reservas, 'lista': lista_espera})
# Verificar si el usuario es administrador
def es_admin(user):
return user.is_staff
@user_passes_test(es_admin)
def crear_evento(request):
if request.method == 'POST':
form = EventoForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Evento creado exitosamente.')
return redirect('eventos:lista_eventos') # Redirige a la lista de eventos
else:
form = EventoForm()
return render(request, 'eventos/crear_evento.html', {'form': form})
@user_passes_test(lambda u: u.is_staff)
def editar_evento(request, evento_id):
evento = get_object_or_404(Evento, id=evento_id)
if request.method == 'POST':
form = EventoForm(request.POST, instance=evento)
if form.is_valid():
form.save()
return redirect('lista_eventos')
else:
form = EventoForm(instance=evento)
return render(request, 'crear_evento.html', {'form': form, 'evento': evento})
@login_required
def apuntar_lista_espera(request, evento_id):
evento = get_object_or_404(Evento, id=evento_id)
# Verificar si el usuario ya está en la lista de espera
if ListaEspera.objects.filter(evento=evento, usuario=request.user).exists():
messages.error(request, 'Ya estás en la lista de espera para este evento.')
return redirect('eventos:lista_eventos')
# Crear una entrada en la lista de espera
if request.method == 'POST':
form = ListaEsperaForm(request.POST)
if form.is_valid():
ListaEspera.objects.create(evento=evento, usuario=request.user)
messages.success(request, 'Te has apuntado a la lista de espera para este evento.')
return redirect('eventos:lista_eventos')
form = ListaEsperaForm()
return render(request, 'eventos/apuntar_lista_espera.html', {'form': form, 'evento': evento})
#
# API
#
@api_view(['GET'])
def api_lista_eventos(request):
"""Devuelve la lista de todos los eventos."""
eventos = Evento.objects.all()
serializer = EventoSerializer(eventos, many=True)
return Response(serializer.data)
@api_view(['GET'])
def api_detalle_evento(request, evento_id):
"""Devuelve los detalles de un evento específico."""
try:
evento = Evento.objects.get(id=evento_id)
serializer = EventoSerializer(evento)
return Response(serializer.data)
except Evento.DoesNotExist:
return Response({'error': 'Evento no encontrado'}, status=404)
@api_view(['GET'])
def api_lista_reservas(request):
"""Devuelve la lista de todos los reservas."""
reservas = Reserva.objects.all()
serializer = ReservaSerializer(reservas, many=True)
return Response(serializer.data)
@api_view(['GET'])
def api_detalle_reserva(request, reserva_id):
"""Devuelve los detalles de un reserva específico."""
try:
reserva = Reserva.objects.get(id=reserva_id)
serializer = ReservaSerializer(reserva)
return Response(serializer.data)
except Reserva.DoesNotExist:
return Response({'error': 'Reserva no encontrado'}, status=404)
@api_view(['GET'])
def api_lista_listaespera(request):
"""Devuelve la lista de todos los listaespera."""
listaesperas = ListaEspera.objects.all()
serializer = ListaEsperaSerializer(listaesperas, many=True)
return Response(serializer.data)
@api_view(['GET'])
def api_detalle_listaespera(request, listaespera_id):
"""Devuelve los detalles de un listaespera específico."""
try:
listaespera = ListaEspera.objects.get(id=listaespera_id)
serializer = ListaEsperaSerializer(listaespera)
return Response(serializer.data)
except ListaEspera.DoesNotExist:
return Response({'error': 'ListaEspera no encontrado'}, status=404)
@api_view(['GET'])
def api_lista_noticias(request):
"""Devuelve la lista de todos los noticias."""
noticias = Noticia.objects.all()
serializer = NoticiaSerializer(noticias, many=True)
return Response(serializer.data)
@api_view(['GET'])
def api_detalle_noticia(request, noticia_id):
"""Devuelve los detalles de un noticia específico."""
try:
noticia = Noticia.objects.get(id=noticia_id)
serializer = NoticiaSerializer(noticia)
return Response(serializer.data)
except Noticia.DoesNotExist:
return Response({'error': 'Noticia no encontrado'}, status=404)
# Verifica si el usuario es administrador
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)
inscritos = Reserva.objects.filter(evento=evento).select_related('usuario')
if not inscritos:
messages.warning(request, "No hay usuarios inscritos en este evento.")
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('eventos:detalle_evento', evento_id=evento.id)
destinatarios_str = ', '.join(destinatarios)
logger.info("destinatarios: " + destinatarios_str)
if request.method == "POST":
form = MensajeCorreoForm(request.POST)
if form.is_valid():
asunto_usuario = form.cleaned_data['asunto']
mensaje_usuario = form.cleaned_data['mensaje']
asunto = f"{asunto_usuario} - {evento.nombre}"
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('eventos:detalle_evento', evento_id=evento.id)
else:
form = MensajeCorreoForm()
return render(request, 'eventos/enviar_correo_inscritos.html', {'form': form, 'evento': evento})