fix tournament deletion signals

bracket-feature
Raz 10 months ago
parent 80ee3e62cf
commit d07ff09ecc
  1. 12
      tournaments/models/tournament.py
  2. 79
      tournaments/services/email_service.py
  3. 56
      tournaments/signals.py

@ -75,6 +75,7 @@ class Tournament(models.Model):
minimum_player_per_team = models.IntegerField(default=2) minimum_player_per_team = models.IntegerField(default=2)
maximum_player_per_team = models.IntegerField(default=2) maximum_player_per_team = models.IntegerField(default=2)
information = models.CharField(max_length=4000, null=True, blank=True) information = models.CharField(max_length=4000, null=True, blank=True)
_being_deleted = False # Class attribute
def __str__(self): def __str__(self):
if self.name: if self.name:
@ -1093,12 +1094,17 @@ class Tournament(models.Model):
def build_tournament_details_str(self): def build_tournament_details_str(self):
tournament_details = [] tournament_details = []
name_str = self.build_name_details_str()
if self.federal_level_category > 0: if self.federal_level_category > 0:
tournament_details.append(self.level()) tournament_details.append(self.level())
if self.category(): if self.category():
tournament_details.append(self.category()) tournament_details.append(self.category())
if self.age(): if self.age():
tournament_details.append(self.age()) tournament_details.append(self.age())
if len(name_str) > 0:
tournament_details.append(name_str)
return " ".join(filter(None, tournament_details)) return " ".join(filter(None, tournament_details))
def build_name_details_str(self): def build_name_details_str(self):
@ -1180,6 +1186,12 @@ class Tournament(models.Model):
return waiting_teams[0].team_registration return waiting_teams[0].team_registration
return None return None
def delete(self, *args, **kwargs):
# Mark this tournament as being deleted
self._being_deleted = True
super().delete(*args, **kwargs)
class MatchGroup: class MatchGroup:
def __init__(self, name, matches, formatted_schedule): def __init__(self, name, matches, formatted_schedule):
self.name = name self.name = name

@ -17,11 +17,9 @@ class TournamentEmailService:
@staticmethod @staticmethod
def send_registration_confirmation(request, tournament, team_registration, waiting_list_position): def send_registration_confirmation(request, tournament, team_registration, waiting_list_position):
tournament_details_str = tournament.build_tournament_details_str() tournament_details_str = tournament.build_tournament_details_str()
name_str = tournament.build_name_details_str()
email_subject = TournamentEmailService._build_email_subject( email_subject = TournamentEmailService._build_email_subject(
tournament_details_str, tournament_details_str,
name_str,
waiting_list_position waiting_list_position
) )
@ -30,7 +28,6 @@ class TournamentEmailService:
tournament, tournament,
team_registration, team_registration,
tournament_details_str, tournament_details_str,
name_str,
waiting_list_position waiting_list_position
) )
@ -44,15 +41,14 @@ class TournamentEmailService:
email.send() email.send()
@staticmethod @staticmethod
def _build_email_subject(tournament_details_str, name_str, waiting_list_position): def _build_email_subject(tournament_details_str, waiting_list_position):
base_subject = f"Confirmation d'inscription au tournoi {tournament_details_str} {name_str}" base_subject = f"Confirmation d'inscription au tournoi {tournament_details_str}"
if waiting_list_position >= 0: if waiting_list_position >= 0:
base_subject = f"En liste d'attente du tournoi {tournament_details_str} {name_str}" base_subject = f"En liste d'attente du tournoi {tournament_details_str}"
return base_subject return base_subject
@staticmethod @staticmethod
def _build_email_body(request, tournament, team_registration, tournament_details_str, def _build_email_body(request, tournament, team_registration, tournament_details_str, waiting_list_position):
name_str, waiting_list_position):
inscription_date = team_registration.local_registration_date().strftime("%d/%m/%Y à %H:%M") inscription_date = team_registration.local_registration_date().strftime("%d/%m/%Y à %H:%M")
team_members = [player.name() for player in team_registration.playerregistration_set.all()] team_members = [player.name() for player in team_registration.playerregistration_set.all()]
team_members_str = " et ".join(team_members) team_members_str = " et ".join(team_members)
@ -61,9 +57,9 @@ class TournamentEmailService:
body_parts.append("Bonjour,\n") body_parts.append("Bonjour,\n")
if waiting_list_position >= 0: if waiting_list_position >= 0:
body_parts.append(f"Votre inscription en liste d'attente du tournoi {tournament_details_str} {name_str} est confirmée.") body_parts.append(f"Votre inscription en liste d'attente du tournoi {tournament_details_str} est confirmée.")
else: else:
body_parts.append(f"Votre inscription au tournoi {tournament_details_str} {name_str} est confirmée.") body_parts.append(f"Votre inscription au tournoi {tournament_details_str} est confirmée.")
absolute_url = f"{request.build_absolute_uri(f'/tournament/{tournament.id}/')}" absolute_url = f"{request.build_absolute_uri(f'/tournament/{tournament.id}/')}"
link_text = "informations sur le tournoi" link_text = "informations sur le tournoi"
@ -85,14 +81,12 @@ class TournamentEmailService:
@staticmethod @staticmethod
def send_unregistration_confirmation(captain, tournament, other_player): def send_unregistration_confirmation(captain, tournament, other_player):
tournament_details_str = tournament.build_tournament_details_str() tournament_details_str = tournament.build_tournament_details_str()
name_str = tournament.build_name_details_str()
email_subject = f"Confirmation de désistement du tournoi {tournament_details_str} {name_str}" email_subject = f"Confirmation de désistement du tournoi {tournament_details_str}"
email_body = TournamentEmailService._build_unregistration_email_body( email_body = TournamentEmailService._build_unregistration_email_body(
tournament, tournament,
captain, captain,
tournament_details_str, tournament_details_str,
name_str,
other_player other_player
) )
@ -110,7 +104,6 @@ class TournamentEmailService:
tournament, tournament,
other_player, other_player,
tournament_details_str, tournament_details_str,
name_str,
captain captain
) )
@ -126,14 +119,12 @@ class TournamentEmailService:
@staticmethod @staticmethod
def send_out_of_waiting_list_confirmation(captain, tournament, other_player): def send_out_of_waiting_list_confirmation(captain, tournament, other_player):
tournament_details_str = tournament.build_tournament_details_str() tournament_details_str = tournament.build_tournament_details_str()
name_str = tournament.build_name_details_str()
email_subject = f"Participation au tournoi {tournament_details_str} {name_str}" email_subject = f"Participation au tournoi {tournament_details_str}"
email_body = TournamentEmailService._buil_out_of_waiting_list_email_body( email_body = TournamentEmailService._buil_out_of_waiting_list_email_body(
tournament, tournament,
captain, captain,
tournament_details_str, tournament_details_str,
name_str,
other_player other_player
) )
@ -151,7 +142,6 @@ class TournamentEmailService:
tournament, tournament,
other_player, other_player,
tournament_details_str, tournament_details_str,
name_str,
captain captain
) )
@ -165,10 +155,10 @@ class TournamentEmailService:
email.send() email.send()
@staticmethod @staticmethod
def _build_unregistration_email_body(tournament, captain, tournament_details_str, name_str, other_player): def _build_unregistration_email_body(tournament, captain, tournament_details_str, other_player):
body_parts = [ body_parts = [
"Bonjour,\n", "Bonjour,\n\n",
f"Votre inscription au tournoi {tournament_details_str} {name_str}, prévu le {tournament.start_date.strftime('%d/%m/%Y')} au club {tournament.event.club.name} a été annulée" f"Votre inscription au tournoi {tournament_details_str}, prévu le {tournament.start_date.strftime('%d/%m/%Y')} au club {tournament.event.club.name} a été annulée"
] ]
if other_player is not None: if other_player is not None:
@ -186,10 +176,10 @@ class TournamentEmailService:
return "".join(body_parts) return "".join(body_parts)
@staticmethod @staticmethod
def _buil_out_of_waiting_list_email_body(tournament, captain, tournament_details_str, name_str, other_player): def _buil_out_of_waiting_list_email_body(tournament, captain, tournament_details_str, other_player):
body_parts = [ body_parts = [
"Bonjour,\n", "Bonjour,\n\n",
f"Suite au désistement d'une paire, vous êtes maintenant inscrit au tournoi {tournament_details_str} {name_str}, prévu le {tournament.start_date.strftime('%d/%m/%Y')} au club {tournament.event.club.name}" f"Suite au désistement d'une paire, vous êtes maintenant inscrit au tournoi {tournament_details_str}, prévu le {tournament.start_date.strftime('%d/%m/%Y')} au club {tournament.event.club.name}"
] ]
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info" absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
@ -212,3 +202,44 @@ class TournamentEmailService:
]) ])
return "".join(body_parts) return "".join(body_parts)
@staticmethod
def send_tournament_cancellation_notification(player, tournament, other_player):
tournament_details_str = tournament.build_tournament_details_str()
email_subject = f"Annulation du tournoi {tournament_details_str}"
email_body = TournamentEmailService._build_tournament_cancellation_email_body(
tournament,
player,
tournament_details_str,
other_player
)
email = EmailMessage(
subject=email_subject,
body=TournamentEmailService._convert_newlines_to_html(email_body),
to=[player.email]
)
email.content_subtype = "html"
email.send()
@staticmethod
def _build_tournament_cancellation_email_body(tournament, player, tournament_details_str, other_player):
body_parts = [
"Bonjour,\n\n",
f"Le tournoi {tournament_details_str}, prévu le {tournament.start_date.strftime('%d/%m/%Y')} au club {tournament.event.club.name} a été annulé par le juge-arbitre."
]
if other_player is not None:
body_parts.append(
f"\nVous étiez inscrit avec {other_player.name()}, n'oubliez pas de prévenir votre partenaire."
)
body_parts.extend([
"\n\nPour toute question, veuillez contacter votre juge-arbitre:",
f"\n{tournament.event.creator.full_name()}\n{tournament.event.creator.email}",
"\n\nCeci est un e-mail automatique, veuillez ne pas y répondre."
])
return "".join(body_parts)

@ -3,6 +3,7 @@ import string
from django.db.models.signals import post_save, pre_delete from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver from django.dispatch import receiver
from django.conf import settings from django.conf import settings
from tournaments.models.tournament import Tournament
from tournaments.models.unregistered_player import UnregisteredPlayer from tournaments.models.unregistered_player import UnregisteredPlayer
from django.utils import timezone from django.utils import timezone
@ -61,14 +62,21 @@ def send_discord_message(webhook_url, content):
@receiver(pre_delete, sender=TeamRegistration) @receiver(pre_delete, sender=TeamRegistration)
def unregister_team(sender, instance, **kwargs): def unregister_team(sender, instance, **kwargs):
team_registration = instance team_registration = instance
tournament=instance.tournament tournament = instance.tournament
# Skip creating unregistration records if tournament is being deleted
if not tournament or tournament._state.adding or hasattr(tournament, '_being_deleted'):
return
first_waiting_list_team = tournament.first_waiting_list_team() first_waiting_list_team = tournament.first_waiting_list_team()
print("Unregistering team from tournament")
# Create unregistered team record
unregistered_team = UnregisteredTeam.objects.create( unregistered_team = UnregisteredTeam.objects.create(
tournament=tournament, tournament=tournament,
unregistration_date=timezone.now(), unregistration_date=timezone.now(),
) )
# Create unregistered player records and track captain/other player
captain = None captain = None
other_player = None other_player = None
for player in team_registration.playerregistration_set.all(): for player in team_registration.playerregistration_set.all():
@ -76,6 +84,7 @@ def unregister_team(sender, instance, **kwargs):
captain = player captain = player
else: else:
other_player = player other_player = player
UnregisteredPlayer.objects.create( UnregisteredPlayer.objects.create(
unregistered_team=unregistered_team, unregistered_team=unregistered_team,
first_name=player.first_name, first_name=player.first_name,
@ -83,6 +92,7 @@ def unregister_team(sender, instance, **kwargs):
licence_id=player.licence_id, licence_id=player.licence_id,
) )
# Handle waiting list notifications
if first_waiting_list_team: if first_waiting_list_team:
waiting_captain = None waiting_captain = None
waiting_other_player = None waiting_other_player = None
@ -92,16 +102,54 @@ def unregister_team(sender, instance, **kwargs):
else: else:
waiting_other_player = player waiting_other_player = player
if waiting_captain is not None and waiting_captain.registered_online == True and waiting_captain.email is not None: if waiting_captain and waiting_captain.registered_online and waiting_captain.email:
TournamentEmailService.send_out_of_waiting_list_confirmation( TournamentEmailService.send_out_of_waiting_list_confirmation(
waiting_captain, waiting_captain,
tournament, tournament,
waiting_other_player waiting_other_player
) )
if captain is not None and captain.registered_online == True and captain.email is not None: # Send unregistration confirmation
if captain and captain.registered_online and captain.email:
TournamentEmailService.send_unregistration_confirmation( TournamentEmailService.send_unregistration_confirmation(
captain, captain,
tournament, tournament,
other_player other_player
) )
@receiver(pre_delete, sender=Tournament)
def notify_players_of_tournament_cancellation(sender, instance, **kwargs):
tournament = instance
# Get all team registrations
team_registrations = tournament.teamregistration_set.all()
for team_registration in team_registrations:
captain = None
other_player = None
# Get players who registered online and have email
for player in team_registration.playerregistration_set.all():
if not player.registered_online:
continue
if player.captain:
captain = player
else:
other_player = player
# Send email to captain
if captain:
TournamentEmailService.send_tournament_cancellation_notification(
captain,
tournament,
other_player
)
# Send email to other player if they exist and registered online
if other_player and other_player.registered_online and other_player.email:
TournamentEmailService.send_tournament_cancellation_notification(
other_player,
tournament,
captain
)

Loading…
Cancel
Save