online_registration
Raz 11 months ago
parent 7f929bfacc
commit 5dd22974e5
  1. 84
      tournaments/models/tournament.py
  2. 71
      tournaments/repositories.py
  3. 111
      tournaments/services/email_service.py
  4. 147
      tournaments/services/tournament_registration.py
  5. 78
      tournaments/services/tournament_unregistration.py
  6. 22
      tournaments/templates/tournaments/tournament_info.html
  7. 49
      tournaments/validators.py
  8. 376
      tournaments/views.py

@ -11,6 +11,7 @@ from django.utils import timezone, formats
from datetime import datetime, timedelta from datetime import datetime, timedelta
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
from tournaments.utils.player_search import get_player_name_from_csv
from shared.cryptography import encryption_util from shared.cryptography import encryption_util
from ..utils.extensions import plural_format from ..utils.extensions import plural_format
@ -1078,6 +1079,89 @@ class Tournament(models.Model):
name_str = f" {name_str}" name_str = f" {name_str}"
return 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: class MatchGroup:
def __init__(self, name, matches, formatted_schedule): def __init__(self, name, matches, formatted_schedule):
self.name = name self.name = name

@ -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

@ -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)

@ -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

@ -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
)

@ -78,21 +78,29 @@
{% endif %} {% endif %}
{% if tournament.online_register_is_enabled and team is None %} {% 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 %} {% if tournament.account_is_required is False or user.is_authenticated and user.is_active %}
{% if user_register_check is None %}
<p> <p>
<div> <div>
<a href="{% url 'register_tournament' tournament.id %}" class="rounded-button">S'inscrire</a> <a href="{% url 'register_tournament' tournament.id %}" class="rounded-button">S'inscrire</a>
</div> </div>
</p> </p>
{% else %} {% else %}
<p>
<div class="semibold">
Vous ne pouvez pas vous inscrire à ce tournoi.
</div>
<div class="alert">
{% for reason in user_register_check %}
<div>{{ reason }}</div>
{% endfor %}
</div>
</p>
{% endif %}
{% else %}
{% for message in messages %} {% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div> <div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %} {% endfor %}
<p> <p>
<div> <div>
<a href="{% url 'login' %}?next={{ request.path }}" class="styled-link">Connectez-vous !</a> <a href="{% url 'login' %}?next={{ request.path }}" class="styled-link">Connectez-vous !</a>
@ -106,11 +114,7 @@
</div> </div>
</p> </p>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>
{% if tournament.online_register_is_enabled and team %} {% if tournament.online_register_is_enabled and team %}

@ -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()

@ -34,6 +34,10 @@ from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.mail import EmailMessage 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 # Local application imports
from .models import ( from .models import (
@ -70,6 +74,7 @@ from api.tokens import account_activation_token
from tournaments.models.device_token import DeviceToken from tournaments.models.device_token import DeviceToken
from tournaments.models.player_enums import PlayerDataSource, PlayerSexType from tournaments.models.player_enums import PlayerDataSource, PlayerSexType
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
from .forms import CustomPasswordChangeForm
def index(request): def index(request):
@ -125,10 +130,12 @@ def tournament_info(request, tournament_id):
registered_user = None registered_user = None
team_registration = None team_registration = None
is_captain = False is_captain = False
user_can_register = True
if request.user.is_authenticated: if request.user.is_authenticated:
# Assuming user's licence_id is stored in the user profile (e.g., request.user.licence_id) # Assuming user's licence_id is stored in the user profile (e.g., request.user.licence_id)
user_licence_id = request.user.licence_id user_licence_id = request.user.licence_id
if user_licence_id is not None: if user_licence_id is not None:
validator = LicenseValidator(user_licence_id) validator = LicenseValidator(user_licence_id)
stripped_license = validator.stripped_license stripped_license = validator.stripped_license
@ -143,11 +150,14 @@ def tournament_info(request, tournament_id):
if registered_user: if registered_user:
is_captain = registered_user.captain is_captain = registered_user.captain
team_registration = registered_user.team_registration team_registration = registered_user.team_registration
else:
user_register_check = tournament.user_register_check(request.user)
return render(request, 'tournaments/tournament_info.html', { return render(request, 'tournaments/tournament_info.html', {
'tournament': tournament, 'tournament': tournament,
'team': team_registration, '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 'user_name': user.username
}) })
from django.views.decorators.csrf import csrf_protect
@csrf_protect @csrf_protect
def register_tournament(request, tournament_id): def register_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, id=tournament_id) tournament = get_object_or_404(Tournament, id=tournament_id)
registration_successful = False # Flag for registration status service = TournamentRegistrationService(request, tournament)
team_form = None service.initialize_context()
add_player_form = None
if 'user_without_licence' not in request.session:
request.session['user_without_licence'] = False
user_without_licence = request.session['user_without_licence']
# Process forms
if request.method == 'POST': if request.method == 'POST':
team_form = TournamentRegistrationForm(request.POST) service.handle_post_request()
# 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: else:
messages.error(request, "Le numéro de licence est invalide, la lettre ne correspond pas.") service.handle_get_request()
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()
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']
})
return render(request, 'register_tournament.html', service.context)
@login_required @login_required
def unregister_tournament(request, tournament_id): def unregister_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, id=tournament_id) tournament = get_object_or_404(Tournament, id=tournament_id)
service = TournamentUnregistrationService(request, tournament)
if not tournament or not tournament.is_unregistration_possible(): if not service.can_unregister():
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) return redirect('tournament-info', tournament_id=tournament_id)
player_registration = PlayerRegistration.objects.filter( service.process_unregistration()
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.")
return redirect('tournament-info', tournament_id=tournament_id) 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()
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): class CustomPasswordResetConfirmView(PasswordResetConfirmView):
template_name = 'registration/password_reset_confirm.html' # Custom template template_name = 'registration/password_reset_confirm.html' # Custom template
@ -1034,8 +698,6 @@ def my_tournaments(request):
'user_name': user.username 'user_name': user.username
}) })
from .forms import CustomPasswordChangeForm
class ProfileUpdateView(UpdateView): class ProfileUpdateView(UpdateView):
model = CustomUser model = CustomUser
form_class = ProfileUpdateForm form_class = ProfileUpdateForm

Loading…
Cancel
Save