from django.utils import timezone from ..forms import TournamentRegistrationForm, AddPlayerForm from ..repositories import TournamentRegistrationRepository from .email_service import TournamentEmailService from django.contrib import messages from ..utils.licence_validator import LicenseValidator from ..utils.player_search import get_player_name_from_csv from tournaments.models import PlayerRegistration from ..utils.extensions import is_not_sqlite_backend class TournamentRegistrationService: def __init__(self, request, tournament): self.request = request self.tournament = tournament self.context = {} self.repository = TournamentRegistrationRepository() 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', []), } 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() if 'remove_player' in self.request.POST: self.handle_remove_player() elif 'register_team' in self.request.POST: self.handle_team_registration() def handle_remove_player(self): team_registration = self.request.session.get('team_registration', []) if team_registration: # Check if list is not empty team_registration.pop() # Remove last element self.request.session['team_registration'] = team_registration self.context['current_players'] = 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 licence_id = player_data.get('licence_id', '').upper() # Validate license if not self._validate_license(licence_id): return # Check for duplicate players if self._is_duplicate_player(licence_id): return # Check if player is already registered in tournament if self._is_already_registered(licence_id): return if self.request.user.licence_id is None and len(self.context['current_players']) == 0: # if no licence id for authentificated user and trying to add him as first player of the team, we check his federal data self._handle_invalid_names(licence_id, player_data) else: # Handle player data if self.context['add_player_form'].names_is_valid(): self._handle_valid_names(player_data) else: self._handle_invalid_names(licence_id, player_data) if self.request.user.is_authenticated and self.request.user.licence_id is None: self._update_user_license(player_data.get('licence_id')) def handle_team_registration(self): if not self.context['team_form'].is_valid(): return if self.request.user.is_authenticated: cleaned_data = self.context['team_form'].cleaned_data mobile_number = cleaned_data.get('mobile_number') self.request.user.phone = mobile_number self.request.user.save() waiting_list_position = self.tournament.get_waiting_list_position() 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 ) if is_not_sqlite_backend(): self.email_service.send_registration_confirmation( self.request, self.tournament, team_registration, waiting_list_position ) 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): print("add_player_to_session", player_data) if not self.request.session.get('team_registration'): self.request.session['team_registration'] = [] self.request.session['team_registration'].append(player_data) self.context['current_players'] = self.request.session.get('team_registration', []) self.context['add_player_form'].first_tournament = False self.context['add_player_form'].user_without_licence = False 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, 'mobile_number': self.request.user.phone, } return TournamentRegistrationForm(initial=initial_data) def initialize_session_data(self): print("initialize_session_data") 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.context['current_players'] = self.request.session.get('team_registration', []) 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.context['add_player_form'].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 ..utils.licence_validator 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'), 'found_in_french_federation': True, }) return player_data def _validate_license(self, licence_id): validator = LicenseValidator(licence_id) if validator.validate_license() is False and self.tournament.license_is_required: if not licence_id: message = ("Le numéro de licence est obligatoire." if not self.request.session.get('team_registration', []) else "Le numéro de licence de votre partenaire est obligatoire.") messages.error(self.request, message) else: # computed_license_key = validator.computed_license_key # messages.error(self.request, f"Le numéro de licence est invalide, la lettre ne correspond pas. {computed_license_key}") messages.error(self.request, "Le numéro de licence est invalide, la lettre ne correspond pas.") return False return True def _is_duplicate_player(self, licence_id): existing_players = [player['licence_id'] for player in self.request.session.get('team_registration', [])] if licence_id in existing_players: messages.error(self.request, "Ce joueur est déjà dans l'équipe.") return True return False def _is_already_registered(self, licence_id): validator = LicenseValidator(licence_id) if (validator.validate_license() and self._license_already_registered(validator.stripped_license) and self.tournament.license_is_required): messages.error(self.request, "Un joueur avec ce numéro de licence est déjà inscrit dans une équipe.") return True return False def _handle_valid_names(self, player_data): print("_handle_valid_names", player_data) if player_data.get('rank') is None: self._set_default_rank(player_data) self.add_player_to_session(player_data) self.context['add_player_form'] = AddPlayerForm() self.context['add_player_form'].first_tournament = False def _handle_invalid_names(self, licence_id, player_data): data, found = get_player_name_from_csv(self.tournament.federal_category, licence_id) print("_handle_invalid_names get_player_name_from_csv", data, found) if found and data: self._update_player_data_from_csv(player_data, data) player_check = self._player_check(player_data) if player_check == True: self.add_player_to_session(player_data) self.context['add_player_form'] = AddPlayerForm() else: return else: print("_handle_first_tournament_case") self._handle_first_tournament_case(data) def _set_default_rank(self, player_data): if self.request.session.get('last_rank') is None: data, found = get_player_name_from_csv(self.tournament.federal_category, None) if data: self.request.session['last_rank'] = data['rank'] self.request.session['is_woman'] = data['is_woman'] self.request.session.modified = True player_data['rank'] = self.request.session.get('last_rank', None) player_data['is_woman'] = self.request.session.get('is_woman', False) def _update_user_license(self, licence_id): if self.request.user.is_authenticated and licence_id: self.context['add_player_form'].user_without_licence = False validator = LicenseValidator(licence_id) self.request.user.licence_id = validator.computed_licence_id self.request.user.save() self.request.user.refresh_from_db() self.request.session.modified = True # Reset the form state self.context['add_player_form'] = AddPlayerForm() self.context['add_player_form'].first_tournament = False def _update_player_data_from_csv(self, player_data, csv_data): print("_update_player_data_from_csv", player_data, csv_data) player_data.update({ 'first_name': csv_data['first_name'], 'last_name': csv_data['last_name'], 'rank': csv_data['rank'], 'is_woman': csv_data['is_woman'], 'points': csv_data.get('points'), 'assimilation': csv_data.get('assimilation'), 'tournament_count': csv_data.get('tournament_count'), 'ligue_name': csv_data.get('ligue_name'), 'club_name': csv_data.get('club_name'), 'birth_year': csv_data.get('birth_year'), 'found_in_french_federation': True, 'email': None, 'phone': None, }) from django.contrib.auth import get_user_model User = get_user_model() # Get the license ID from player_data licence_id = player_data.get('licence_id') validator = LicenseValidator(licence_id) if validator and validator.stripped_license: try: # Try to find a user with matching license user_with_same_license = User.objects.get(licence_id__icontains=validator.stripped_license) # If found, update the email and phone if user_with_same_license: player_data.update({ 'email': user_with_same_license.email, 'phone': user_with_same_license.phone }) print(f"Found user with license {licence_id}, updated email and phone") except User.DoesNotExist: # No user found with this license, continue with None email and phone pass def _handle_first_tournament_case(self, data): print("_handle_first_tournament_case", data) if data: self.request.session['last_rank'] = data['rank'] self.request.session['is_woman'] = data['is_woman'] self.request.session.modified = True self.context['add_player_form'].first_tournament = True if not self.context['add_player_form'].names_is_valid(): message = ("Pour confirmer votre inscription votre prénom et votre nom sont obligatoires." if not self.request.session.get('team_registration', []) else "Pour rajouter un partenaire, son prénom et son nom sont obligatoires.") messages.error(self.request, message) def _player_check(self, player_data): licence_id = player_data['licence_id'].upper() validator = LicenseValidator(licence_id) is_license_valid = validator.validate_license() player_register_check = self.tournament.player_register_check(licence_id) if is_license_valid and player_register_check is not None: for message in player_register_check: messages.error(self.request, message) return False return True def _license_already_registered(self, stripped_license): return PlayerRegistration.objects.filter( team_registration__tournament=self.tournament, licence_id__icontains=stripped_license, team_registration__walk_out=False ).exists()