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.
438 lines
19 KiB
438 lines
19 KiB
from django.core.mail import EmailMessage
|
|
from django.utils import timezone
|
|
from django.urls import reverse
|
|
from enum import Enum
|
|
|
|
class TeamEmailType(Enum):
|
|
UNREGISTERED = "unregistered"
|
|
OUT_OF_WAITING_LIST = "out_of_waiting_list"
|
|
TOURNAMENT_CANCELED = "tournament_canceled"
|
|
IN_TOURNAMENT_STRUCTURE = "in_tournament_structure"
|
|
OUT_OF_TOURNAMENT_STRUCTURE = "out_of_tournament_structure"
|
|
OUT_OF_WALKOUT_IS_IN = "out_of_walkout_is_in"
|
|
OUT_OF_WALKOUT_WAITING_LIST = "out_of_walkout_waiting_list"
|
|
WALKOUT = "walkout"
|
|
UNEXPECTED_OUT_OF_TOURNAMENT = 'unexpected_out_of_tournament'
|
|
|
|
def email_subject(self) -> str:
|
|
subjects = {
|
|
self.UNREGISTERED: "Désistement",
|
|
self.OUT_OF_WAITING_LIST: "Participation confirmée",
|
|
self.TOURNAMENT_CANCELED: "Tournoi annulé",
|
|
self.IN_TOURNAMENT_STRUCTURE: "Participation confirmée",
|
|
self.OUT_OF_TOURNAMENT_STRUCTURE: "Participation annulée",
|
|
self.OUT_OF_WALKOUT_IS_IN: "Participation confirmée",
|
|
self.OUT_OF_WALKOUT_WAITING_LIST: "Liste d'attente",
|
|
self.WALKOUT: "Participation annulée",
|
|
self.UNEXPECTED_OUT_OF_TOURNAMENT: "Participation annulée",
|
|
}
|
|
return subjects.get(self, "Tournament Notification")
|
|
|
|
class TournamentEmailService:
|
|
@staticmethod
|
|
def _convert_newlines_to_html(text):
|
|
html_content = text.replace('\n', '<br>')
|
|
return f"""
|
|
<html>
|
|
<body>
|
|
{html_content}
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
@staticmethod
|
|
def email_subject(tournament, topic):
|
|
base_subject = f"[{tournament.build_tournament_type_str()}] [{tournament.formatted_start_date()}] " + topic
|
|
return base_subject
|
|
|
|
@staticmethod
|
|
def send_registration_confirmation(request, tournament, team_registration, waiting_list_position):
|
|
tournament_details_str = tournament.build_tournament_details_str()
|
|
|
|
email_subject = TournamentEmailService._build_email_subject(
|
|
tournament,
|
|
tournament_details_str,
|
|
waiting_list_position
|
|
)
|
|
|
|
email_body = TournamentEmailService._build_email_body(
|
|
request,
|
|
tournament,
|
|
team_registration,
|
|
tournament_details_str,
|
|
waiting_list_position
|
|
)
|
|
TournamentEmailService._send_email(request.user.email, email_subject, email_body)
|
|
|
|
@staticmethod
|
|
def _build_email_subject(tournament, tournament_details_str, waiting_list_position):
|
|
if waiting_list_position >= 0:
|
|
base_subject = "Liste d'attente"
|
|
else:
|
|
base_subject = "Participation confirmé"
|
|
return TournamentEmailService.email_subject(tournament, base_subject)
|
|
|
|
@staticmethod
|
|
def _build_email_body(request, tournament, team_registration, tournament_details_str, waiting_list_position):
|
|
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_str = " et ".join(team_members)
|
|
|
|
body_parts = []
|
|
body_parts.append("Bonjour,\n")
|
|
|
|
if waiting_list_position >= 0:
|
|
body_parts.append(f"Votre inscription en liste d'attente du tournoi {tournament_details_str} est confirmée.")
|
|
else:
|
|
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}/')}"
|
|
link_text = "informations sur le tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
body_parts.extend([
|
|
f"\nDate d'inscription: {inscription_date}",
|
|
f"\nÉquipe inscrite: {team_members_str}",
|
|
f"\nLe tournoi commencera le {tournament.formatted_start_date()} au club {tournament.event.club.name}",
|
|
f"\nVoir les {absolute_url}",
|
|
"\nPour toute question, veuillez contacter votre juge-arbitre. Si vous n'êtes pas à l'origine de cette inscription, merci de le contacter rapidement.",
|
|
f"\n{tournament.event.creator.full_name()}\n{tournament.event.creator.email}",
|
|
"\nCeci est un e-mail automatique, veuillez ne pas y répondre.",
|
|
"\nCordialement,\n\nPadel Club"
|
|
])
|
|
|
|
return "\n".join(body_parts)
|
|
|
|
@staticmethod
|
|
def _build_unregistration_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"Votre inscription au tournoi {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name} a été annulée"
|
|
]
|
|
|
|
if other_player is not None:
|
|
body_parts.append(
|
|
f"\n\nVous étiez inscrit avec {other_player.name()}, n'oubliez pas de prévenir votre partenaire."
|
|
)
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "informations sur le tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
body_parts.append(
|
|
f"\n\nVoir les {absolute_url}",
|
|
)
|
|
|
|
body_parts.extend([
|
|
"\n\nPour toute question, veuillez contacter votre juge-arbitre. "
|
|
"Si vous n'êtes pas à l'origine de cette désinscription, merci de le contacter rapidement.",
|
|
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)
|
|
|
|
@staticmethod
|
|
def _build_out_of_waiting_list_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"Suite au désistement d'une paire, vous êtes maintenant inscrit au tournoi {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name}"
|
|
]
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "accéder au tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
if other_player is not None:
|
|
body_parts.append(
|
|
f"\nVoici le partenaire indiqué dans l'inscription : {other_player.name()}, n'oubliez pas de le prévenir."
|
|
)
|
|
|
|
body_parts.append(
|
|
"\n\nSi vous n'êtes plus disponible pour participer à ce tournoi, cliquez sur ce lien ou contactez rapidement le juge-arbitre."
|
|
f"\n{absolute_url}"
|
|
"\nPour vous désinscrire en ligne vous devez avoir un compte Padel Club."
|
|
)
|
|
|
|
body_parts.extend([
|
|
f"\n\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)
|
|
|
|
@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.formatted_start_date()} 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)
|
|
|
|
@staticmethod
|
|
def _build_in_tournament_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"Suite à une modification de la taille du tournoi, vous pouvez participer au tournoi {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name}"
|
|
]
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "accéder au tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
if other_player is not None:
|
|
body_parts.append(
|
|
f"\nVoici le partenaire indiqué dans l'inscription : {other_player.name()}, n'oubliez pas de le prévenir."
|
|
)
|
|
|
|
body_parts.append(
|
|
"\n\nSi vous n'êtes plus disponible pour participer à ce tournoi, cliquez sur ce lien ou contactez rapidement le juge-arbitre."
|
|
f"\n{absolute_url}"
|
|
"\nPour vous désinscrire en ligne vous devez avoir un compte Padel Club."
|
|
)
|
|
|
|
body_parts.extend([
|
|
f"\n\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)
|
|
|
|
@staticmethod
|
|
def _build_out_of_tournament_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"Suite à une modification de la taille du tournoi, vous ne faites plus partie des équipes participant au tournoi {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name}"
|
|
]
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "informations sur le tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
body_parts.append(f"\n\nVoir les {absolute_url}")
|
|
|
|
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)
|
|
|
|
@staticmethod
|
|
def _build_walk_out_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"Le juge-arbitre a annulé votre participation au tournoi {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name}"
|
|
]
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "accéder au tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
body_parts.append(f"\n\nVoir les {absolute_url}")
|
|
|
|
|
|
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)
|
|
|
|
@staticmethod
|
|
def _build_out_of_walkout_is_in_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"Le juge-arbitre vous a ré-intégré au tournoi {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name}"
|
|
]
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "informations sur le tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
body_parts.append(f"\n\nVoir les {absolute_url}")
|
|
|
|
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)
|
|
|
|
@staticmethod
|
|
def _build_unexpected_out_of_tournament_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"En raison d'une décision du juge-arbitre, vous ne faites plus partie des équipes participant au tournoi {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name}"
|
|
]
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "informations sur le tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
body_parts.append(f"\n\nVoir les {absolute_url}")
|
|
|
|
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)
|
|
|
|
@staticmethod
|
|
def _build_out_of_walkout_waiting_list_email_body(tournament, captain, tournament_details_str, other_player):
|
|
body_parts = [
|
|
"Bonjour,\n\n",
|
|
f"Le juge-arbitre vous a ré-intégré au tournoi en liste d'attente {tournament_details_str}, prévu le {tournament.formatted_start_date()} au club {tournament.event.club.name}"
|
|
]
|
|
|
|
absolute_url = f"https://padelclub.app/tournament/{tournament.id}/info"
|
|
link_text = "informations sur le tournoi"
|
|
absolute_url = f'<a href="{absolute_url}">{link_text}</a>'
|
|
|
|
body_parts.append(f"\n\nVoir les {absolute_url}")
|
|
|
|
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)
|
|
|
|
@staticmethod
|
|
def notify(captain, other_player, tournament, message_type: TeamEmailType):
|
|
if not captain or not captain.registered_online or not captain.email:
|
|
return
|
|
|
|
tournament_details_str = tournament.build_tournament_details_str()
|
|
|
|
email_body = TournamentEmailService._build_email_content(
|
|
message_type, captain, tournament, tournament_details_str, other_player
|
|
)
|
|
|
|
if email_body is None:
|
|
return
|
|
|
|
topic = message_type.email_subject()
|
|
email_subject = TournamentEmailService.email_subject(tournament, topic)
|
|
TournamentEmailService._send_email(captain.email, email_subject, email_body)
|
|
|
|
@staticmethod
|
|
def _build_email_content(message_type, recipient, tournament, tournament_details_str, other_player):
|
|
if message_type == TeamEmailType.OUT_OF_WAITING_LIST:
|
|
body = TournamentEmailService._build_out_of_waiting_list_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.UNREGISTERED:
|
|
body = TournamentEmailService._build_unregistration_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.TOURNAMENT_CANCELED:
|
|
body = TournamentEmailService._build_tournament_cancellation_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.WALKOUT:
|
|
body = TournamentEmailService._build_walk_out_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.OUT_OF_WALKOUT_IS_IN:
|
|
body = TournamentEmailService._build_out_of_walkout_is_in_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.OUT_OF_WALKOUT_WAITING_LIST:
|
|
body = TournamentEmailService._build_out_of_walkout_waiting_list_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.UNEXPECTED_OUT_OF_TOURNAMENT:
|
|
body = TournamentEmailService._build_unexpected_out_of_tournament_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.OUT_OF_TOURNAMENT_STRUCTURE:
|
|
body = TournamentEmailService._build_out_of_tournament_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
elif message_type == TeamEmailType.IN_TOURNAMENT_STRUCTURE:
|
|
body = TournamentEmailService._build_in_tournament_email_body(
|
|
tournament, recipient, tournament_details_str, other_player
|
|
)
|
|
else:
|
|
return None
|
|
|
|
return body
|
|
|
|
@staticmethod
|
|
def _send_email(to, subject, body):
|
|
email = EmailMessage(
|
|
subject=subject,
|
|
body=TournamentEmailService._convert_newlines_to_html(body),
|
|
to=[to]
|
|
)
|
|
email.content_subtype = "html"
|
|
email.send()
|
|
print("TournamentEmailService._send_email", to, subject)
|
|
|
|
@staticmethod
|
|
def notify_team(team, tournament, message_type: TeamEmailType):
|
|
captain = None
|
|
other_player = None
|
|
|
|
for player in team.playerregistration_set.all():
|
|
if player.captain:
|
|
captain = player
|
|
else:
|
|
other_player = player
|
|
|
|
if captain:
|
|
TournamentEmailService.notify(captain, other_player, tournament, message_type)
|
|
else:
|
|
# Notify both players separately if there is no captain or the captain is unavailable
|
|
players = list(team.playerregistration_set.all())
|
|
if len(players) == 2:
|
|
first_player, second_player = players
|
|
TournamentEmailService.notify(first_player, second_player, tournament, message_type)
|
|
TournamentEmailService.notify(second_player, first_player, tournament, message_type)
|
|
elif len(players) == 1:
|
|
# If there's only one player, just send them the notification
|
|
TournamentEmailService.notify(players[0], None, tournament, message_type)
|
|
|