diff --git a/tournaments/models/tournament.py b/tournaments/models/tournament.py
index a35b1b9..77c05d1 100644
--- a/tournaments/models/tournament.py
+++ b/tournaments/models/tournament.py
@@ -11,6 +11,7 @@ from django.utils import timezone, formats
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
+from tournaments.utils.player_search import get_player_name_from_csv
from shared.cryptography import encryption_util
from ..utils.extensions import plural_format
@@ -1078,6 +1079,89 @@ class Tournament(models.Model):
name_str = f" {name_str}"
return name_str
+ def user_register_check(self, user):
+ reasons = []
+
+ if not user.licence_id:
+ return None
+
+ data, found = get_player_name_from_csv(self.federal_category, user.licence_id)
+ if not found or not data:
+ return None
+
+ birth_year = data.get('birth_year', None)
+ is_woman = data.get('is_woman', None)
+
+ # Check gender category restrictions
+ if is_woman is not None and self.federal_category == FederalCategory.WOMEN and is_woman is False:
+ reasons.append("Ce tournoi est réservé aux femmes")
+
+ if birth_year is None:
+ return reasons if reasons else None
+
+ current_year = timezone.now().year
+ if timezone.now().month >= 9: # Check if current month is September or later
+ current_year += 1
+
+ user_age = current_year - int(birth_year)
+
+ # Check age category restrictions
+ if self.federal_age_category == FederalAgeCategory.A11_12 and user_age > 12:
+ reasons.append("Ce tournoi est réservé aux -12 ans")
+ if self.federal_age_category == FederalAgeCategory.A13_14 and user_age > 14:
+ reasons.append("Ce tournoi est réservé aux -14 ans")
+ if self.federal_age_category == FederalAgeCategory.A15_16 and user_age > 16:
+ reasons.append("Ce tournoi est réservé aux -16 ans")
+ if self.federal_age_category == FederalAgeCategory.A17_18 and user_age > 18:
+ reasons.append("Ce tournoi est réservé aux -18 ans")
+ if self.federal_age_category == FederalAgeCategory.A45 and user_age < 45:
+ reasons.append("Ce tournoi est réservé aux +45 ans")
+ if self.federal_age_category == FederalAgeCategory.A55 and user_age < 55:
+ reasons.append("Ce tournoi est réservé aux +55 ans")
+
+ return reasons if reasons else None
+def user_can_register(self, user):
+ if not user.licence_id:
+ return True
+
+ data, found = get_player_name_from_csv(self.federal_category, user.licence_id)
+ if not found:
+ return True
+ if not data:
+ return True
+
+ birth_year = data.get('birth_year', None)
+ is_woman = data.get('is_woman', None)
+
+ # Check gender category restrictions
+ if is_woman is not None and self.federal_category == FederalCategory.WOMEN and is_woman is False:
+ return False
+
+ if birth_year is None:
+ return True
+
+ current_year = timezone.now().year
+ if timezone.now().month >= 9: # Check if current month is September or later
+ current_year += 1
+
+ user_age = current_year - int(birth_year)
+
+ # Check age category restrictions
+ if self.federal_age_category == FederalAgeCategory.A11_12 and user_age > 12:
+ return False
+ if self.federal_age_category == FederalAgeCategory.A13_14 and user_age > 14:
+ return False
+ if self.federal_age_category == FederalAgeCategory.A15_16 and user_age > 16:
+ return False
+ if self.federal_age_category == FederalAgeCategory.A17_18 and user_age > 18:
+ return False
+ if self.federal_age_category == FederalAgeCategory.A45 and user_age < 45:
+ return False
+ if self.federal_age_category == FederalAgeCategory.A55 and user_age < 55:
+ return False
+
+ return True
+
class MatchGroup:
def __init__(self, name, matches, formatted_schedule):
self.name = name
diff --git a/tournaments/repositories.py b/tournaments/repositories.py
new file mode 100644
index 0000000..6d621ea
--- /dev/null
+++ b/tournaments/repositories.py
@@ -0,0 +1,71 @@
+from django.utils import timezone
+from .models import TeamRegistration, PlayerRegistration
+from .models.player_enums import PlayerSexType, PlayerDataSource
+from .models.enums import FederalCategory
+from tournaments.utils.licence_validator import LicenseValidator
+
+class TournamentRegistrationRepository:
+ @staticmethod
+ def create_team_registration(tournament, registration_date):
+ team_registration = TeamRegistration.objects.create(
+ tournament=tournament,
+ registration_date=registration_date
+ )
+ return team_registration
+
+ @staticmethod
+ def create_player_registrations(request, team_registration, players_data, team_form_data):
+ stripped_license = None
+ if request.user.is_authenticated and request.user.licence_id:
+ stripped_license = LicenseValidator(request.user.licence_id).stripped_license
+
+ for player_data in players_data:
+ is_captain = False
+ player_licence_id = player_data['licence_id']
+ if player_licence_id and stripped_license:
+ if player_licence_id.startswith(stripped_license):
+ is_captain = True
+
+ sex, rank, computed_rank = TournamentRegistrationRepository._compute_rank_and_sex(
+ team_registration.tournament,
+ player_data
+ )
+
+ player_registration = PlayerRegistration.objects.create(
+ team_registration=team_registration,
+ captain=is_captain,
+ source=PlayerDataSource.ONLINE_REGISTRATION,
+ first_name=player_data.get('first_name'),
+ last_name=player_data.get('last_name'),
+ points=player_data.get('points'),
+ assimilation=player_data.get('assimilation'),
+ tournament_played=player_data.get('tournament_count'),
+ ligue_name=player_data.get('ligue_name'),
+ club_name=player_data.get('club_name'),
+ birthdate=player_data.get('birth_year'),
+ sex=sex,
+ rank=rank,
+ computed_rank=computed_rank,
+ licence_id=player_data['licence_id'],
+ email=team_form_data['email'],
+ phone_number=team_form_data['mobile_number']
+ )
+ player_registration.save()
+
+ team_registration.set_weight()
+ team_registration.save()
+
+ @staticmethod
+ def _compute_rank_and_sex(tournament, player_data):
+ is_woman = player_data.get('is_woman', False)
+ rank = player_data.get('rank', 0)
+ computed_rank = rank
+ sex = PlayerSexType.MALE
+
+ if is_woman:
+ sex = PlayerSexType.FEMALE
+ if tournament.federal_category == FederalCategory.MEN:
+ computed_rank = str(int(computed_rank) +
+ FederalCategory.female_in_male_assimilation_addition(int(rank)))
+
+ return sex, rank, computed_rank
diff --git a/tournaments/services/email_service.py b/tournaments/services/email_service.py
new file mode 100644
index 0000000..b799bf7
--- /dev/null
+++ b/tournaments/services/email_service.py
@@ -0,0 +1,111 @@
+from django.core.mail import EmailMessage
+from django.utils import timezone
+
+class TournamentEmailService:
+ @staticmethod
+ def send_registration_confirmation(request, tournament, team_registration):
+ waiting_list_position = tournament.get_waiting_list_position()
+ tournament_details_str = tournament.build_tournament_details_str()
+ name_str = tournament.build_name_details_str()
+
+ email_subject = TournamentEmailService._build_email_subject(
+ tournament_details_str,
+ name_str,
+ waiting_list_position
+ )
+
+ email_body = TournamentEmailService._build_email_body(
+ request,
+ tournament,
+ team_registration,
+ tournament_details_str,
+ name_str,
+ waiting_list_position
+ )
+
+ email = EmailMessage(
+ subject=email_subject,
+ body=email_body,
+ to=[request.user.email]
+ )
+ email.send()
+
+ @staticmethod
+ def _build_email_subject(tournament_details_str, name_str, waiting_list_position):
+ base_subject = f"Confirmation d'inscription au tournoi {tournament_details_str}{name_str}"
+ if waiting_list_position >= 0:
+ base_subject = f"En liste d'attente du tournoi {tournament_details_str}{name_str}"
+ return base_subject
+
+ @staticmethod
+ def _build_email_body(request, tournament, team_registration, tournament_details_str,
+ name_str, waiting_list_position):
+ inscription_date = timezone.now().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(f"Bonjour,\n")
+
+ 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.")
+ else:
+ body_parts.append(f"Votre inscription au tournoi{tournament_details_str}{name_str} est confirmée.")
+
+ body_parts.extend([
+ f"\nDate d'inscription: {inscription_date}",
+ f"\nÉquipe inscrite: {team_members_str}",
+ f"\nLe tournoi commencera le {tournament.start_date.strftime('%d/%m/%Y')} @ {tournament.event.club.name}",
+ f"\nVoir les informations sur {request.build_absolute_uri(f'/tournament/{tournament.id}/')}",
+ "\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 send_unregistration_confirmation(request, tournament, other_player):
+ 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_body = TournamentEmailService._build_unregistration_email_body(
+ request,
+ tournament,
+ tournament_details_str,
+ name_str,
+ other_player
+ )
+
+ email = EmailMessage(
+ subject=email_subject,
+ body=email_body,
+ to=[request.user.email]
+ )
+ email.send()
+
+ @staticmethod
+ def _build_unregistration_email_body(request, tournament, tournament_details_str,
+ name_str, other_player):
+ body_parts = [
+ f"Bonjour,\n",
+ f"Vous venez de vous désinscrire du tournoi {tournament_details_str}{name_str}",
+ f" du {tournament.start_date.strftime('%d/%m/%Y')} @ {tournament.event.club.name}"
+ ]
+
+ if other_player:
+ body_parts.append(
+ f"\n\nVous étiez inscrit avec {other_player.name()}, n'oubliez pas de prévenir votre partenaire."
+ )
+
+ body_parts.extend([
+ f"\n\nVoir les informations sur {request.build_absolute_uri(f'/tournament/{tournament.id}/')}",
+ "\n\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}",
+ "\n\nCeci est un e-mail automatique, veuillez ne pas y répondre."
+ ])
+
+ return "".join(body_parts)
diff --git a/tournaments/services/tournament_registration.py b/tournaments/services/tournament_registration.py
new file mode 100644
index 0000000..658bb84
--- /dev/null
+++ b/tournaments/services/tournament_registration.py
@@ -0,0 +1,147 @@
+from django.utils import timezone
+from ..forms import TournamentRegistrationForm, AddPlayerForm
+from ..validators import TournamentRegistrationValidator
+from ..repositories import TournamentRegistrationRepository
+from .email_service import TournamentEmailService
+
+class TournamentRegistrationService:
+ def __init__(self, request, tournament):
+ self.request = request
+ self.tournament = tournament
+ self.context = {}
+ self.repository = TournamentRegistrationRepository()
+ self.validator = TournamentRegistrationValidator()
+ self.email_service = TournamentEmailService()
+
+ def initialize_context(self):
+ self.context = {
+ 'tournament': self.tournament,
+ 'registration_successful': False,
+ 'team_form': None,
+ 'add_player_form': None,
+ 'current_players': self.request.session.get('team_registration', []),
+ 'user_without_licence': self.request.session.get('user_without_licence', False)
+ }
+ return self.context
+
+ def handle_post_request(self):
+ self.context['team_form'] = TournamentRegistrationForm(self.request.POST)
+ self.context['add_player_form'] = AddPlayerForm(self.request.POST)
+
+ if 'add_player' in self.request.POST:
+ self.handle_add_player()
+ elif 'register_team' in self.request.POST:
+ self.handle_team_registration()
+
+ def handle_add_player(self):
+ if not self.context['add_player_form'].is_valid():
+ return
+
+ player_data = self.context['add_player_form'].cleaned_data
+ if not self.validator.validate_player_license(self.request, self.tournament, player_data):
+ return
+
+ self.add_player_to_session(player_data)
+ self.context['add_player_form'] = AddPlayerForm()
+
+ def handle_team_registration(self):
+ if not self.context['team_form'].is_valid():
+ return
+
+ team_registration = self.repository.create_team_registration(
+ self.tournament,
+ timezone.now().replace(microsecond=0)
+ )
+
+ self.repository.create_player_registrations(
+ self.request,
+ team_registration,
+ self.request.session['team_registration'],
+ self.context['team_form'].cleaned_data
+ )
+
+ self.email_service.send_registration_confirmation(
+ self.request,
+ self.tournament,
+ team_registration
+ )
+
+ self.clear_session_data()
+ self.context['registration_successful'] = True
+
+ def handle_get_request(self):
+ self.context['add_player_form'] = AddPlayerForm()
+ self.context['team_form'] = self.initialize_team_form()
+ self.initialize_session_data()
+
+ def add_player_to_session(self, player_data):
+ if not self.request.session.get('team_registration'):
+ self.request.session['team_registration'] = []
+
+ self.request.session['team_registration'].append(player_data)
+ self.request.session.modified = True
+
+ def clear_session_data(self):
+ self.request.session['team_registration'] = []
+ self.request.session.modified = True
+
+ def initialize_team_form(self):
+ initial_data = {}
+ if self.request.user.is_authenticated:
+ initial_data = {
+ 'email': self.request.user.email,
+ 'phone': self.request.user.phone,
+ }
+ return TournamentRegistrationForm(initial=initial_data)
+
+ def initialize_session_data(self):
+ self.request.session['team_registration'] = []
+ if self.request.user.is_authenticated:
+ self._add_authenticated_user_to_session()
+
+ def _add_authenticated_user_to_session(self):
+ if not self.request.user.licence_id:
+ self._handle_user_without_license()
+ return
+
+ player_data = self._get_authenticated_user_data()
+ if player_data:
+ self.request.session['team_registration'].insert(0, player_data)
+ self.request.session.modified = True
+
+ def _handle_user_without_license(self):
+ player_data = {
+ 'first_name': self.request.user.first_name,
+ 'last_name': self.request.user.last_name.upper(),
+ }
+ self.context['add_player_form'] = AddPlayerForm(initial=player_data)
+ self.request.session['user_without_licence'] = True
+ self.request.session.modified = True
+
+ def _get_authenticated_user_data(self):
+ from ..utils.player_search import get_player_name_from_csv
+ from ..validators import LicenseValidator
+ user = self.request.user
+ validator = LicenseValidator(user.licence_id)
+
+ player_data = {
+ 'first_name': user.first_name,
+ 'last_name': user.last_name.upper(),
+ 'email': user.email,
+ 'phone': user.phone,
+ 'licence_id': validator.computed_licence_id
+ }
+
+ data, found = get_player_name_from_csv(self.tournament.federal_category, user.licence_id)
+ if found and data:
+ player_data.update({
+ 'rank': data['rank'],
+ 'points': data.get('points'),
+ 'assimilation': data.get('assimilation'),
+ 'tournament_count': data.get('tournament_count'),
+ 'ligue_name': data.get('ligue_name'),
+ 'club_name': data.get('club_name'),
+ 'birth_year': data.get('birth_year')
+ })
+
+ return player_data
diff --git a/tournaments/services/tournament_unregistration.py b/tournaments/services/tournament_unregistration.py
new file mode 100644
index 0000000..010189f
--- /dev/null
+++ b/tournaments/services/tournament_unregistration.py
@@ -0,0 +1,78 @@
+from django.contrib import messages
+from django.utils import timezone
+from ..models import PlayerRegistration, UnregisteredTeam, UnregisteredPlayer
+from ..models.player_enums import PlayerDataSource
+from ..services.email_service import TournamentEmailService
+
+class TournamentUnregistrationService:
+ def __init__(self, request, tournament):
+ self.request = request
+ self.tournament = tournament
+ self.player_registration = None
+ self.other_player = None
+
+ def can_unregister(self):
+ if not self.tournament.is_unregistration_possible():
+ messages.error(self.request, "Le désistement n'est plus possible pour ce tournoi.")
+ return False
+
+ if not self.request.user.licence_id:
+ messages.error(self.request,
+ "Vous ne pouvez pas vous désinscrire car vous n'avez pas de numéro de licence associé.")
+ return False
+
+ return True
+
+ def process_unregistration(self):
+ if not self._find_player_registration():
+ messages.error(self.request,
+ "La désincription a échouée. Veuillez contacter le juge-arbitre.")
+ return False
+
+ self._create_unregistered_team()
+ self._send_unregistration_email()
+ self._cleanup_session()
+ return True
+
+ def _find_player_registration(self):
+ self.player_registration = PlayerRegistration.objects.filter(
+ licence_id__startswith=self.request.user.licence_id,
+ team_registration__tournament_id=self.tournament.id,
+ ).first()
+
+ if self.player_registration:
+ team_registration = self.player_registration.team_registration
+ self.other_player = team_registration.get_other_player(self.player_registration)
+ return True
+ return False
+
+ def _create_unregistered_team(self):
+ team_registration = self.player_registration.team_registration
+
+ unregistered_team = UnregisteredTeam.objects.create(
+ tournament=self.tournament,
+ unregistration_date=timezone.now(),
+ )
+
+ for player in team_registration.playerregistration_set.all():
+ UnregisteredPlayer.objects.create(
+ unregistered_team=unregistered_team,
+ first_name=player.first_name,
+ last_name=player.last_name,
+ licence_id=player.licence_id,
+ )
+
+ team_registration.delete()
+
+ def _cleanup_session(self):
+ self.request.session['team_registration'] = []
+
+ def _send_unregistration_email(self):
+ if not self.request.user.email:
+ return
+
+ TournamentEmailService.send_unregistration_confirmation(
+ self.request,
+ self.tournament,
+ self.other_player
+ )
diff --git a/tournaments/templates/tournaments/tournament_info.html b/tournaments/templates/tournaments/tournament_info.html
index f4f35a5..8a29253 100644
--- a/tournaments/templates/tournaments/tournament_info.html
+++ b/tournaments/templates/tournaments/tournament_info.html
@@ -78,39 +78,43 @@
{% endif %}
{% if tournament.online_register_is_enabled and team is None %}
-
- {% if tournament.account_is_required is False or user.is_authenticated and user.is_active %}
-
-
-
-
- {% else %}
-
- {% for message in messages %}
- {{ message }}
- {% endfor %}
-
-
-
-
-
-
-
-
-
- {% endif %}
-
-
-
+ {% if tournament.account_is_required is False or user.is_authenticated and user.is_active %}
+ {% if user_register_check is None %}
+
+
+
+ {% else %}
+
+
+ Vous ne pouvez pas vous inscrire à ce tournoi.
+
+
+ {% for reason in user_register_check %}
+
{{ reason }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% else %}
+ {% for message in messages %}
+ {{ message }}
+ {% endfor %}
+
+
+
+
+
+
+
+ {% endif %}
{% endif %}
-
{% if tournament.online_register_is_enabled and team %}
diff --git a/tournaments/validators.py b/tournaments/validators.py
new file mode 100644
index 0000000..d6ffdc5
--- /dev/null
+++ b/tournaments/validators.py
@@ -0,0 +1,49 @@
+from django.contrib import messages
+from .models import PlayerRegistration
+from tournaments.utils.licence_validator import LicenseValidator
+# Remove unused import since get_player_name_from_csv is not used in this class
+
+class TournamentRegistrationValidator:
+ @staticmethod
+ def validate_player_license(request, tournament, player_data):
+ licence_id = player_data['licence_id'].upper()
+ validator = LicenseValidator(licence_id)
+
+ if not validator.validate_license() and tournament.license_is_required:
+ TournamentRegistrationValidator._handle_invalid_license(request, licence_id)
+ return False
+
+ if validator.validate_license() and TournamentRegistrationValidator._is_duplicate_license(
+ licence_id, request.session['team_registration']):
+ messages.error(request, "Ce joueur est déjà dans l'équipe.")
+ return False
+
+ if validator.validate_license() and tournament.license_is_required:
+ stripped_license = validator.stripped_license
+ if TournamentRegistrationValidator._license_already_registered(stripped_license, tournament):
+ messages.error(request, "Un joueur avec ce numéro de licence est déjà inscrit dans une équipe.")
+ return False
+
+ return True
+
+ @staticmethod
+ def _handle_invalid_license(request, licence_id):
+ if not licence_id:
+ if not request.session.get('team_registration'):
+ messages.error(request, "Le numéro de licence est obligatoire.")
+ else:
+ messages.error(request, "Le numéro de licence de votre partenaire est obligatoire.")
+ else:
+ messages.error(request, "Le numéro de licence est invalide, la lettre ne correspond pas.")
+
+ @staticmethod
+ def _is_duplicate_license(licence_id, team_registration):
+ existing_licenses = [player['licence_id'] for player in team_registration]
+ return licence_id in existing_licenses
+
+ @staticmethod
+ def _license_already_registered(stripped_license, tournament):
+ return PlayerRegistration.objects.filter(
+ team_registration__tournament=tournament,
+ licence_id__startswith=stripped_license
+ ).exists()
diff --git a/tournaments/views.py b/tournaments/views.py
index 2700533..4e0bfc6 100644
--- a/tournaments/views.py
+++ b/tournaments/views.py
@@ -34,6 +34,10 @@ from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.core.mail import EmailMessage
+from django.views.decorators.csrf import csrf_protect
+from .services.tournament_registration import TournamentRegistrationService
+from .services.tournament_unregistration import TournamentUnregistrationService
+
# Local application imports
from .models import (
@@ -70,6 +74,7 @@ from api.tokens import account_activation_token
from tournaments.models.device_token import DeviceToken
from tournaments.models.player_enums import PlayerDataSource, PlayerSexType
from django.views.generic.edit import UpdateView
+from .forms import CustomPasswordChangeForm
def index(request):
@@ -125,10 +130,12 @@ def tournament_info(request, tournament_id):
registered_user = None
team_registration = None
is_captain = False
+ user_can_register = True
if request.user.is_authenticated:
# Assuming user's licence_id is stored in the user profile (e.g., request.user.licence_id)
user_licence_id = request.user.licence_id
+
if user_licence_id is not None:
validator = LicenseValidator(user_licence_id)
stripped_license = validator.stripped_license
@@ -143,11 +150,14 @@ def tournament_info(request, tournament_id):
if registered_user:
is_captain = registered_user.captain
team_registration = registered_user.team_registration
+ else:
+ user_register_check = tournament.user_register_check(request.user)
return render(request, 'tournaments/tournament_info.html', {
'tournament': tournament,
'team': team_registration,
- 'is_captain': is_captain
+ 'is_captain': is_captain,
+ 'user_register_check': user_register_check
})
@@ -596,376 +606,30 @@ def profile(request):
'user_name': user.username
})
-from django.views.decorators.csrf import csrf_protect
-
@csrf_protect
def register_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, id=tournament_id)
- registration_successful = False # Flag for registration status
- team_form = None
- add_player_form = None
- if 'user_without_licence' not in request.session:
- request.session['user_without_licence'] = False
+ service = TournamentRegistrationService(request, tournament)
+ service.initialize_context()
- user_without_licence = request.session['user_without_licence']
-
- # Process forms
if request.method == 'POST':
- team_form = TournamentRegistrationForm(request.POST)
- # Check if the add player form is submitted
- add_player_form = AddPlayerForm(request.POST)
- if 'add_player' in request.POST and add_player_form.is_valid():
- player_data = add_player_form.cleaned_data
- # Validate the license ID before adding the player
- licence_id = player_data['licence_id'].upper()
- # Instantiate your custom validator and validate the license ID
-
- validator = LicenseValidator(licence_id)
- if validator.validate_license() is False and tournament.license_is_required is True:
- if len(licence_id) == 0:
- if len(request.session.get('team_registration', [])) == 0:
- messages.error(request, "Le numéro de licence est obligatoire.")
- else:
- messages.error(request, "Le numéro de licence de votre partenaire est obligatoire.")
- else:
- messages.error(request, "Le numéro de licence est invalide, la lettre ne correspond pas.")
- return render(request, 'register_tournament.html', {
- 'team_form': team_form,
- 'add_player_form': add_player_form,
- 'tournament': tournament,
- 'registration_successful': registration_successful,
- 'current_players': request.session['team_registration'],
- 'user_without_licence': user_without_licence
- })
-
- # Check if the player with the same licence_id already exists in the session
- existing_players = [player['licence_id'] for player in request.session['team_registration']]
- if validator.validate_license() and licence_id in existing_players:
- messages.error(request, "Ce joueur est déjà dans l'équipe.")
- return render(request, 'register_tournament.html', {
- 'team_form': team_form,
- 'add_player_form': add_player_form,
- 'tournament': tournament,
- 'registration_successful': registration_successful,
- 'current_players': request.session['team_registration'],
- 'user_without_licence': user_without_licence
- })
- else:
- # Check if a PlayerRegistration with the same licence_id already exists in the database
- stripped_license = validator.stripped_license
- if validator.validate_license() and validate_license_id(stripped_license, tournament) and tournament.license_is_required is True:
- messages.error(request, "Un joueur avec ce numéro de licence est déjà inscrit dans une équipe.")
- return render(request, 'register_tournament.html', {
- 'team_form': team_form,
- 'add_player_form': add_player_form,
- 'tournament': tournament,
- 'registration_successful': registration_successful,
- 'current_players': request.session['team_registration'],
- 'user_without_licence': user_without_licence
- })
- elif add_player_form.names_is_valid():
- if player_data.get('rank', None) is None:
- if request.session.get('last_rank', None) is None:
- data, found = get_player_name_from_csv(tournament.federal_category, None)
- if data:
- request.session['last_rank'] = data['rank']
- request.session['is_woman'] = data['is_woman']
- request.session.modified = True
- player_data['rank'] = request.session.get('last_rank', 0)
- player_data['is_woman'] = request.session.get('is_woman', False)
- request.session['team_registration'].append(player_data)
- if request.user.is_authenticated and request.user.licence_id is None:
- request.session['user_without_licence'] = False
- request.user.licence_id = validator.computed_licence_id
- request.user.save()
- request.session.modified = True # Ensure session is updated
- add_player_form = AddPlayerForm()
-
- else:
- if add_player_form.first_tournament is False:
- # Retrieve player names from the CSV file
- data, found = get_player_name_from_csv(tournament.federal_category, licence_id)
- if found and data:
- player_data['first_name'] = data['first_name']
- player_data['last_name'] = data['last_name']
- player_data['rank'] = data['rank']
- player_data['is_woman'] = data['is_woman']
- # If validation passes, add the player to the session without clearing previous ones
- request.session['team_registration'].append(player_data)
- request.session.modified = True # Ensure session is updated
- add_player_form = AddPlayerForm()
- else:
- if data:
- request.session['last_rank'] = data['rank']
- request.session['is_woman'] = data['is_woman']
- request.session.modified = True # Ensure session is updated
- add_player_form.first_tournament = True
- if add_player_form.names_is_valid() is False:
- if len(request.session.get('team_registration', [])) == 0:
- messages.error(request, "Pour confirmer votre inscription votre prénom et votre nom sont obligatoires.")
- else:
- messages.error(request, "Pour rajouter un partenaire, son prénom et son nom sont obligatoires.")
- return render(request, 'register_tournament.html', {
- 'team_form': team_form,
- 'add_player_form': add_player_form,
- 'tournament': tournament,
- 'registration_successful': registration_successful,
- 'current_players': request.session['team_registration'],
- 'user_without_licence': user_without_licence
- })
-
-
-
-
- # Check if the team registration form is valid and finalize the registration
- elif 'register_team' in request.POST and team_form.is_valid():
- waiting_list_position = tournament.get_waiting_list_position()
- registration_date = timezone.now().replace(microsecond=0)
- team_registration = TeamRegistration.objects.create(
- tournament=tournament,
- registration_date=registration_date
- )
-
- stripped_license = None
- if request.user.is_authenticated and request.user.licence_id is not None:
- stripped_license = LicenseValidator(request.user.licence_id).stripped_license
-
- # Create PlayerRegistration objects for each player in the session
- for player_data in request.session['team_registration']:
- is_captain = False
- player_licence_id = player_data['licence_id']
- if player_licence_id is not None and stripped_license is not None:
- if player_licence_id.startswith(stripped_license):
- is_captain = True
-
- is_woman = player_data.get('is_woman', False)
- rank = player_data.get('rank', 0)
- computed_rank = None
- sex = PlayerSexType.MALE
- if is_woman is None:
- computed_rank = rank
- else:
- computed_rank = rank
- is_woman = player_data.get('is_woman', False) == True
- if is_woman:
- sex = PlayerSexType.FEMALE
- if tournament.federal_category == FederalCategory.MEN and is_woman:
- computed_rank = str(int(computed_rank) + FederalCategory.female_in_male_assimilation_addition(int(rank)))
-
-
- player_registration = PlayerRegistration.objects.create(
- team_registration=team_registration,
- captain=is_captain,
- source=PlayerDataSource.ONLINE_REGISTRATION,
- first_name=player_data.get('first_name', None),
- last_name=player_data.get('last_name', None),
- points=player_data.get('points', None),
- assimilation=player_data.get('assimilation', None),
- tournament_played=player_data.get('tournament_count', None),
- ligue_name=player_data.get('ligue_name', None),
- club_name=player_data.get('club_name', None),
- birthdate=player_data.get('birth_year', None),
- sex = sex,
- rank = rank,
- computed_rank = computed_rank,
- licence_id=player_data['licence_id'],
- email = team_form.cleaned_data['email'],
- phone_number = team_form.cleaned_data['mobile_number']
- )
- player_registration.save()
-
- team_registration.set_weight()
- team_registration.save()
-
- request.session['team_registration'] = []
- registration_successful = True
-
- # Send confirmation email
- tournament_details_str = tournament.build_tournament_details_str()
- name_str = tournament.build_name_details_str()
-
- email_subject = f"Confirmation d'inscription au tournoi {tournament_details_str}{name_str}"
- if waiting_list_position >= 0:
- email_subject = f"En liste d'attente du tournoi {tournament_details_str}{name_str}"
-
- inscription_date = timezone.now().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)
-
- email_body = f"Bonjour,\n\nVotre inscription au tournoi{tournament_details_str}{name_str} est confirmée."
- if tournament.get_waiting_list_position() >= 0:
- email_body = f"Bonjour,\n\nVotre inscription en liste d'attente du tournoi{tournament_details_str}{name_str} est confirmée."
-
- email_body += f"\n\nDate d'inscription: {inscription_date}"
- email_body += f"\n\nÉquipe inscrite: {team_members_str}"
- email_body += f"\n\nLe tournoi commencera le {tournament.start_date.strftime('%d/%m/%Y')}"
- email_body += f" @ {tournament.event.club.name}"
- email_body += f"\n\nVoir les informations sur {request.build_absolute_uri(f'/tournament/{tournament.id}/')}"
- email_body += "\n\nPour toute question, veuillez contacter votre juge-arbitre. Si vous n'êtes pas à l'origine de cette inscription, merci de le contacter rapidement."
- email_body += f"\n{tournament.event.creator.full_name()}\n{tournament.event.creator.email}"
- email_body += "\n\nCeci est un e-mail automatique, veuillez ne pas y répondre."
-
- email_body += "\n\nCordialement,\n\nPadel Club"
-
-
- email = EmailMessage(
- subject=email_subject,
- body=email_body,
- to=[team_form.cleaned_data['email']]
- )
- email.send()
+ service.handle_post_request()
else:
- add_player_form = AddPlayerForm()
-
- request.session['team_registration'] = []
- initial_data = {}
- player_data = {}
-
- # Add the authenticated user to the session as the first player if not already added
- if request.user.is_authenticated:
- user_licence_id = request.user.licence_id
- initial_data = {
- 'email': request.user.email,
- 'phone': request.user.phone,
- }
-
- if user_licence_id is not None:
- validator = LicenseValidator(user_licence_id)
- existing_players = [player['licence_id'] for player in request.session['team_registration']]
- if user_licence_id not in existing_players:
- # Add the authenticated user as the first player in the session
- player_data = {
- 'first_name': request.user.first_name,
- 'last_name': request.user.last_name.upper(),
- 'email': request.user.email,
- 'phone': request.user.phone,
- 'licence_id': validator.computed_licence_id
- }
-
- data, found = get_player_name_from_csv(tournament.federal_category, user_licence_id)
- if found and data:
- player_data['rank'] = data['rank']
- player_data['points'] = data.get('points', None)
- player_data['assimilation'] = data.get('assimilation', None)
- player_data['tournament_count'] = data.get('tournament_count', None)
- player_data['ligue_name'] = data.get('ligue_name', None)
- player_data['club_name'] = data.get('club_name', None)
- player_data['birth_year'] = data.get('birth_year', None)
-
- request.session['team_registration'].insert(0, player_data) # Add them as the first player
- request.session.modified = True # Ensure session is updated
- else:
- player_data = {
- 'first_name': request.user.first_name,
- 'last_name': request.user.last_name.upper(),
- }
- add_player_form = AddPlayerForm(initial=player_data)
- request.session['user_without_licence'] = True
- request.session.modified = True # Ensure session is updated
- user_without_licence = True
-
- team_form = TournamentRegistrationForm(initial=initial_data)
- return render(request, 'register_tournament.html', {
- 'team_form': team_form,
- 'add_player_form': add_player_form,
- 'tournament': tournament,
- 'registration_successful': registration_successful,
- 'current_players': request.session['team_registration'],
- 'user_without_licence': request.session['user_without_licence']
- })
-
-
+ service.handle_get_request()
+ return render(request, 'register_tournament.html', service.context)
@login_required
def unregister_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, id=tournament_id)
+ service = TournamentUnregistrationService(request, tournament)
- if not tournament or not tournament.is_unregistration_possible():
- messages.error(request, "Le désistement n'est plus possible pour ce tournoi.")
- return redirect('tournament-info', tournament_id=tournament_id)
-
- user_licence_id = request.user.licence_id
- if not user_licence_id:
- messages.error(request, "Vous ne pouvez pas vous désinscrire car vous n'avez pas de numéro de licence associé.")
- return redirect('tournament-info', tournament_id=tournament_id)
-
- player_registration = PlayerRegistration.objects.filter(
- licence_id__startswith=user_licence_id,
- team_registration__tournament_id=tournament_id,
- source=PlayerDataSource.ONLINE_REGISTRATION,
- ).first() # Get the first match, if any
-
- other_player = None
- if player_registration:
- team_registration = player_registration.team_registration # Get the related TeamRegistration
- other_player = team_registration.get_other_player(player_registration)
-
- unregistered_team = UnregisteredTeam.objects.create(
- tournament=tournament,
- unregistration_date=timezone.now(),
- )
-
- for player in team_registration.playerregistration_set.all():
- unregistered_player = UnregisteredPlayer.objects.create(
- unregistered_team=unregistered_team,
- first_name=player.first_name,
- last_name=player.last_name,
- licence_id=player.licence_id,
- )
- unregistered_player.save()
-
- unregistered_team.save()
- team_registration.delete()
-
- else:
- messages.error(request, "La désincription a échouée. Veuillez contacter le juge-arbitre.")
+ if not service.can_unregister():
return redirect('tournament-info', tournament_id=tournament_id)
- request.session['team_registration'] = []
- # Get the tournament information and player details before deleting
- if tournament and request.user.email: # Ensure we have valid tournament and user email
- 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_body = f"Bonjour,\n\nVous venez de vous désinscrire du tournoi{tournament_details_str}{name_str}"
- email_body += f" du {tournament.start_date.strftime('%d/%m/%Y')}"
- email_body += f" au {tournament.event.club.name}"
- if other_player is not None:
- email_body += f"\n\nVous étiez inscrit avec {other_player.name()}, n'oubliez pas de prévenir votre partenaire."
-
- email_body += f"\n\nVoir les informations sur {request.build_absolute_uri(f'/tournament/{tournament.id}/')}"
- email_body += "\n\nPour toute question, veuillez contacter votre juge-arbitre. Si vous n'êtes pas à l'origine de cette inscription, merci de le contacter rapidement."
- email_body += f"\n{tournament.event.creator.full_name()}\n{tournament.event.creator.email}"
- email_body += "\n\nCeci est un e-mail automatique, veuillez ne pas y répondre."
-
- email = EmailMessage(
- subject=email_subject,
- body=email_body,
- to=[request.user.email]
- )
- email.send()
-
+ service.process_unregistration()
return redirect('tournament-info', tournament_id=tournament_id)
-def validate_license_id(licence_id, tournament):
- teams = TeamRegistration.objects.filter(tournament=tournament)
-
- # Filter out walkouts and unregistered teams
- teams = teams.filter(walk_out=False)
-
- # Check if any player in any team in the tournament already has this licence_id
- # Normalize the licence ID before querying
- # Loop through each team and check if any of its players has the same licence_id
- for team in teams:
- for player in team.playerregistration_set.all():
- if player.licence_id is not None and player.licence_id.startswith(licence_id):
- return True
-
- # If all checks pass, return True (you can add further logic here if needed)
- return False
-
class CustomPasswordResetConfirmView(PasswordResetConfirmView):
template_name = 'registration/password_reset_confirm.html' # Custom template
@@ -1034,8 +698,6 @@ def my_tournaments(request):
'user_name': user.username
})
-from .forms import CustomPasswordChangeForm
-
class ProfileUpdateView(UpdateView):
model = CustomUser
form_class = ProfileUpdateForm