From 3bd4007acc8e959d57e0abffb425da3f9db9125a Mon Sep 17 00:00:00 2001
From: Raz
Date: Thu, 3 Apr 2025 13:31:20 +0200
Subject: [PATCH] fix licence-id stuff
---
tournaments/forms.py | 32 ++++-
tournaments/models/enums.py | 35 ++++++
tournaments/models/tournament.py | 57 ++-------
.../services/tournament_registration.py | 51 +++++---
.../tournaments/tournament_info.html | 110 +++++++++---------
tournaments/utils/licence_validator.py | 4 +-
6 files changed, 163 insertions(+), 126 deletions(-)
diff --git a/tournaments/forms.py b/tournaments/forms.py
index 872514b..ea3fc96 100644
--- a/tournaments/forms.py
+++ b/tournaments/forms.py
@@ -15,7 +15,12 @@ class CustomUserCreationForm(UserCreationForm):
def clean_licence_id(self):
licence_id = self.cleaned_data.get('licence_id')
if licence_id:
- return licence_id.replace(' ', '').strip().upper()
+ licence_id = licence_id.replace(' ', '').strip().upper()
+ validator = LicenseValidator(licence_id)
+ if validator.validate_license():
+ licence_id = validator.computed_licence_id
+ else:
+ raise forms.ValidationError('Le numéro de licence est invalide, la lettre ne correspond pas.')
return licence_id
class Meta:
@@ -41,7 +46,12 @@ class SimpleCustomUserCreationForm(UserCreationForm):
def clean_licence_id(self):
licence_id = self.cleaned_data.get('licence_id')
if licence_id:
- return licence_id.replace(' ', '').strip().upper()
+ licence_id = licence_id.replace(' ', '').strip().upper()
+ validator = LicenseValidator(licence_id)
+ if validator.validate_license():
+ licence_id = validator.computed_licence_id
+ else:
+ raise forms.ValidationError('Le numéro de licence est invalide, la lettre ne correspond pas.')
return licence_id
def clean_phone(self):
@@ -91,6 +101,17 @@ class SimpleCustomUserCreationForm(UserCreationForm):
class CustomUserChangeForm(UserChangeForm):
+ def clean_licence_id(self):
+ print("CustomUserChangeForm")
+ licence_id = self.cleaned_data.get('licence_id')
+ if licence_id:
+ licence_id = licence_id.replace(' ', '').strip().upper()
+ validator = LicenseValidator(licence_id)
+ if validator.validate_license():
+ licence_id = validator.computed_licence_id
+ else:
+ raise forms.ValidationError('Le numéro de licence est invalide, la lettre ne correspond pas.')
+ return licence_id
class Meta:
model = CustomUser
@@ -209,7 +230,12 @@ class ProfileUpdateForm(forms.ModelForm):
def clean_licence_id(self):
licence_id = self.cleaned_data.get('licence_id')
if licence_id:
- return licence_id.replace(' ', '').upper()
+ licence_id = licence_id.replace(' ', '').strip().upper()
+ validator = LicenseValidator(licence_id)
+ if validator.validate_license():
+ licence_id = validator.computed_licence_id
+ else:
+ raise forms.ValidationError('Le numéro de licence est invalide, la lettre ne correspond pas.')
return licence_id
def clean_phone(self):
diff --git a/tournaments/models/enums.py b/tournaments/models/enums.py
index 8a2f5e4..c92c2c1 100644
--- a/tournaments/models/enums.py
+++ b/tournaments/models/enums.py
@@ -148,6 +148,41 @@ class OnlineRegistrationStatus(models.IntegerChoices):
ENDED_WITH_RESULTS = 8, 'Ended with Results'
CANCELED = 9, 'Canceled'
+ def display_register_option(self) -> bool:
+ status_map = {
+ OnlineRegistrationStatus.OPEN: True,
+ OnlineRegistrationStatus.NOT_ENABLED: False,
+ OnlineRegistrationStatus.NOT_STARTED: False,
+ OnlineRegistrationStatus.ENDED: False,
+ OnlineRegistrationStatus.WAITING_LIST_POSSIBLE: True,
+ OnlineRegistrationStatus.WAITING_LIST_FULL: False,
+ OnlineRegistrationStatus.IN_PROGRESS: False,
+ OnlineRegistrationStatus.ENDED_WITH_RESULTS: False,
+ OnlineRegistrationStatus.CANCELED: False
+ }
+ return status_map.get(self, False)
+
+ def register_button_text(self) -> str:
+ if self == OnlineRegistrationStatus.OPEN:
+ return "S'inscrire"
+ elif self == OnlineRegistrationStatus.NOT_ENABLED:
+ return "Inscription désactivée"
+ elif self == OnlineRegistrationStatus.NOT_STARTED:
+ return "Ouverture des inscriptions à venir"
+ elif self == OnlineRegistrationStatus.ENDED:
+ return "Inscription terminée"
+ elif self == OnlineRegistrationStatus.WAITING_LIST_POSSIBLE:
+ return "S'inscrire en liste d'attente"
+ elif self == OnlineRegistrationStatus.WAITING_LIST_FULL:
+ return "Liste d'attente complète"
+ elif self == OnlineRegistrationStatus.IN_PROGRESS:
+ return "Tournoi en cours"
+ elif self == OnlineRegistrationStatus.ENDED_WITH_RESULTS:
+ return "Tournoi terminé"
+ elif self == OnlineRegistrationStatus.CANCELED:
+ return "Tournoi annulé"
+ return ""
+
def status_localized(self) -> str:
status_map = {
OnlineRegistrationStatus.OPEN: "Inscription ouverte",
diff --git a/tournaments/models/tournament.py b/tournaments/models/tournament.py
index 00dde56..13d4679 100644
--- a/tournaments/models/tournament.py
+++ b/tournaments/models/tournament.py
@@ -1066,42 +1066,6 @@ class Tournament(BaseModel):
return options
- def online_register_is_enabled(self):
- if self.supposedly_in_progress():
- return False
- if self.closed_registration_date is not None:
- return False
- if self.end_date is not None:
- return False
-
- now = timezone.now()
-
- # Check if online registration is enabled
- if not self.enable_online_registration:
- return False
-
- # Check opening registration date
- if self.opening_registration_date is not None:
- timezoned_datetime = timezone.localtime(self.opening_registration_date)
- if now < timezoned_datetime:
- return False
-
- # Check registration date limit
- if self.registration_date_limit is not None:
- timezoned_datetime = timezone.localtime(self.registration_date_limit)
- if now > timezoned_datetime:
- return False
-
- # Check target team count and waiting list limit
- if self.team_count is not None:
- current_team_count = self.team_registrations.exclude(walk_out=True).count()
- if current_team_count >= self.team_count:
- if self.waiting_list_limit is not None:
- waiting_list_count = current_team_count - self.team_count
- if waiting_list_count >= self.waiting_list_limit:
- return False
- return True
-
def get_selection_status_localized(self):
if self.team_sorting == TeamSortingType.RANK:
return "La sélection se fait par le poids de l'équipe"
@@ -1552,18 +1516,17 @@ class Tournament(BaseModel):
return None
validator = LicenseValidator(licence_id)
- stripped_license = validator.stripped_license
+ if validator.validate_license():
+ stripped_license = validator.stripped_license
+ # Check if there is a PlayerRegistration for this user in this tournament
+ user_player = PlayerRegistration.objects.filter(
+ licence_id__icontains=stripped_license,
+ team_registration__tournament=self,
+ ).first()
+ if user_player:
+ return user_player.get_registration_status()
- # Check if there is a PlayerRegistration for this user in this tournament
- user_player = PlayerRegistration.objects.filter(
- licence_id__icontains=stripped_license,
- team_registration__tournament=self,
- ).first()
-
- if user_player:
- return user_player.get_registration_status()
- else:
- return None
+ return None
class MatchGroup:
diff --git a/tournaments/services/tournament_registration.py b/tournaments/services/tournament_registration.py
index d42ae9e..09b8403 100644
--- a/tournaments/services/tournament_registration.py
+++ b/tournaments/services/tournament_registration.py
@@ -7,6 +7,9 @@ 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
+from django.contrib.auth import get_user_model
+from django.contrib.messages import get_messages
+from django.db import IntegrityError
class TournamentRegistrationService:
def __init__(self, request, tournament):
@@ -70,6 +73,10 @@ class TournamentRegistrationService:
if self._is_already_registered(licence_id):
return
+ if self.request.user.is_authenticated and self.request.user.licence_id is None:
+ if self._update_user_license(player_data.get('licence_id')) == False:
+ 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)
@@ -80,9 +87,6 @@ class TournamentRegistrationService:
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
@@ -119,7 +123,7 @@ class TournamentRegistrationService:
self.context['registration_successful'] = True
def handle_get_request(self):
- from django.contrib.messages import get_messages
+ print("handle_get_request")
storage = get_messages(self.request)
# Iterate through the storage to clear it
for _ in storage:
@@ -180,8 +184,6 @@ class TournamentRegistrationService:
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)
@@ -209,6 +211,7 @@ class TournamentRegistrationService:
return player_data
def _validate_license(self, licence_id):
+ print("Validating license...")
validator = LicenseValidator(licence_id)
if validator.validate_license() is False and self.tournament.license_is_required:
@@ -221,6 +224,7 @@ class TournamentRegistrationService:
# 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.")
+ print("License validation failed")
return False
return True
@@ -276,16 +280,26 @@ class TournamentRegistrationService:
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
+ if not self.request.user.is_authenticated or not licence_id:
+ return False
+
+ self.context['add_player_form'].user_without_licence = False
+ validator = LicenseValidator(licence_id)
+
+ if validator.validate_license():
+ computed_licence_id = validator.computed_licence_id
+ try:
+ self.request.user.licence_id = computed_licence_id
+ self.request.user.save()
+ self.request.user.refresh_from_db()
+ self.request.session.modified = True
+ return True
+
+ except IntegrityError:
+ # Handle the duplicate license error
+ error_msg = f"Ce numéro de licence ({computed_licence_id}) est déjà utilisé par un autre joueur."
+ messages.error(self.request, error_msg)
+ return False
def _update_player_data_from_csv(self, player_data, csv_data):
print("_update_player_data_from_csv", player_data, csv_data)
@@ -305,16 +319,15 @@ class TournamentRegistrationService:
'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:
+ if validator.validate_license():
try:
# Try to find a user with matching license
- user_with_same_license = User.objects.get(licence_id__icontains=validator.stripped_license)
+ user_with_same_license = User.objects.get(licence_id__iexact=validator.computed_licence_id)
# If found, update the email and phone
if user_with_same_license:
diff --git a/tournaments/templates/tournaments/tournament_info.html b/tournaments/templates/tournaments/tournament_info.html
index 1035ab0..d3a112b 100644
--- a/tournaments/templates/tournaments/tournament_info.html
+++ b/tournaments/templates/tournaments/tournament_info.html
@@ -111,75 +111,75 @@
{% endif %}
- {% if tournament.enable_online_registration %}
-
-
-
Inscription en ligne
-
- {% if tournament.options_online_registration %}
-
- {% for option in tournament.options_online_registration %}
- - {{ option }}
- {% endfor %}
-
- {% endif %}
-
+ {% with status=tournament.get_online_registration_status %}
+ {% if tournament.enable_online_registration %}
+
+
Inscription en ligne
-
-
- {% if tournament.registration_count_display %}
-
{{ tournament.registration_count_display }}
- {% else %}
-
Aucune équipe inscrite
- {% endif %}
-
-
+ {% if tournament.options_online_registration %}
+
+ {% for option in tournament.options_online_registration %}
+ - {{ option }}
+ {% endfor %}
+
+ {% endif %}
+
-
-
- {{ tournament.get_online_registration_status.status_localized }}
-
-
+
+
+ {% if tournament.registration_count_display %}
+
{{ tournament.registration_count_display }}
+ {% else %}
+
Aucune équipe inscrite
+ {% endif %}
+
+
- {% endif %}
+
+
+ {{ status.status_localized }}
+
+
+ {% 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 %}
- {% if player_register_check is None %}
+ {% if status.display_register_option and team is None %}
+ {% if tournament.account_is_required is False or user.is_authenticated and user.is_active %}
+ {% if player_register_check is None %}
+
+
+
+ {% else %}
+
+
+ Vous ne pouvez pas vous inscrire à ce tournoi.
+
+
+ {% for reason in player_register_check %}
+
{{ reason }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% else %}
- {% else %}
+
-
- Vous ne pouvez pas vous inscrire à ce tournoi.
+
+ Vous avez besoin d'un compte Padel Club pour pouvoir vous inscrire en ligne.
-
- {% for reason in player_register_check %}
-
{{ reason }}
- {% endfor %}
+
{% endif %}
- {% else %}
-
-
-
-
-
-
- Vous avez besoin d'un compte Padel Club pour pouvoir vous inscrire en ligne.
-
-
-
{% endif %}
- {% endif %}
+ {% endwith %}
diff --git a/tournaments/utils/licence_validator.py b/tournaments/utils/licence_validator.py
index 2f00e8d..59935ad 100644
--- a/tournaments/utils/licence_validator.py
+++ b/tournaments/utils/licence_validator.py
@@ -15,7 +15,7 @@ class LicenseValidator:
@property
def computed_licence_id(self) -> str:
- return f"{self.stripped_license}{self.computed_license_key}"
+ return f"{self.stripped_license}{self.computed_license_key.upper()}"
@property
def computed_license_key(self) -> str:
@@ -45,4 +45,4 @@ class LicenseValidator:
given_letter = self.license_id[-1]
# Verify that the last character matches the computed license key
- return self.computed_license_key == given_letter
+ return self.computed_licence_id == numeric_part + given_letter