From 28161b1fbb4dae0d4ac6e549f9c050d7d47ce3bd Mon Sep 17 00:00:00 2001
From: Raz
Date: Sat, 8 Mar 2025 08:55:47 +0100
Subject: [PATCH 1/4] fix online register
---
tournaments/models/enums.py | 2 +
tournaments/repositories.py | 13 ++++--
.../services/tournament_registration.py | 40 +++++++++++++------
.../services/tournament_unregistration.py | 2 +-
.../templates/register_tournament.html | 24 ++++++++++-
tournaments/utils/player_search.py | 4 +-
tournaments/views.py | 4 +-
7 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/tournaments/models/enums.py b/tournaments/models/enums.py
index c3f3be6..fa2c263 100644
--- a/tournaments/models/enums.py
+++ b/tournaments/models/enums.py
@@ -15,6 +15,8 @@ class FederalCategory(models.IntegerChoices):
@staticmethod
def female_in_male_assimilation_addition(rank: int) -> int:
+ if rank is None:
+ return 0
if 1 <= rank <= 10:
return 400
elif 11 <= rank <= 30:
diff --git a/tournaments/repositories.py b/tournaments/repositories.py
index d33690f..cd394bd 100644
--- a/tournaments/repositories.py
+++ b/tournaments/repositories.py
@@ -23,7 +23,7 @@ class TournamentRegistrationRepository:
is_captain = False
player_licence_id = player_data['licence_id']
if player_licence_id and stripped_license:
- if player_licence_id.startswith(stripped_license):
+ if stripped_license.lower() in player_licence_id.lower():
is_captain = True
sex, rank, computed_rank = TournamentRegistrationRepository._compute_rank_and_sex(
@@ -31,6 +31,7 @@ class TournamentRegistrationRepository:
player_data
)
+ print("create_player_registrations", player_data.get('last_name'), sex, rank, computed_rank)
data_source = None
if player_data.get('found_in_french_federation', False) == True:
data_source = PlayerDataSource.FRENCH_FEDERATION
@@ -66,14 +67,18 @@ class TournamentRegistrationRepository:
@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
+ rank = player_data.get('rank', None)
+ if rank is None:
+ computed_rank = 100000
+ else:
+ 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)))
+ print("_compute_rank_and_sex", sex, rank, computed_rank)
return sex, rank, computed_rank
diff --git a/tournaments/services/tournament_registration.py b/tournaments/services/tournament_registration.py
index 90492ba..8f033f0 100644
--- a/tournaments/services/tournament_registration.py
+++ b/tournaments/services/tournament_registration.py
@@ -31,9 +31,18 @@ class TournamentRegistrationService:
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
@@ -106,6 +115,7 @@ class TournamentRegistrationService:
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'] = []
@@ -216,6 +226,7 @@ class TournamentRegistrationService:
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)
@@ -224,18 +235,19 @@ class TournamentRegistrationService:
self.context['add_player_form'].first_tournament = False
def _handle_invalid_names(self, licence_id, player_data):
- if not self.context['add_player_form'].first_tournament:
- data, found = get_player_name_from_csv(self.tournament.federal_category, licence_id)
- 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
+ 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:
- self._handle_first_tournament_case(data)
+ 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:
@@ -245,7 +257,7 @@ class TournamentRegistrationService:
self.request.session['is_woman'] = data['is_woman']
self.request.session.modified = True
- player_data['rank'] = self.request.session.get('last_rank', 0)
+ 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):
@@ -261,6 +273,7 @@ class TournamentRegistrationService:
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'],
@@ -278,6 +291,7 @@ class TournamentRegistrationService:
})
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']
@@ -307,6 +321,6 @@ class TournamentRegistrationService:
def _license_already_registered(self, stripped_license):
return PlayerRegistration.objects.filter(
team_registration__tournament=self.tournament,
- licence_id__startswith=stripped_license,
+ licence_id__icontains=stripped_license,
team_registration__walk_out=False
).exists()
diff --git a/tournaments/services/tournament_unregistration.py b/tournaments/services/tournament_unregistration.py
index cfad4c4..aa932e0 100644
--- a/tournaments/services/tournament_unregistration.py
+++ b/tournaments/services/tournament_unregistration.py
@@ -53,7 +53,7 @@ class TournamentUnregistrationService:
def _find_player_registration(self):
self.player_registration = PlayerRegistration.objects.filter(
- licence_id__startswith=self.request.user.licence_id,
+ licence_id__icontains=self.request.user.licence_id,
team_registration__tournament_id=self.tournament.id,
).first()
diff --git a/tournaments/templates/register_tournament.html b/tournaments/templates/register_tournament.html
index 5d5a262..0210214 100644
--- a/tournaments/templates/register_tournament.html
+++ b/tournaments/templates/register_tournament.html
@@ -23,7 +23,7 @@
{% if registration_successful %}
Merci, l'inscription a bien été envoyée au juge-arbitre.
- Un email de confirmation a été envoyé à {{ user.email }} pour confirmer votre inscription. Pensez à vérifier vos spams si vous ne recevez pas l'email. En cas de problème, contactez le juge-arbitre.
+ Un email de confirmation a été envoyé à l'adresse associée à votre compte Padel Club ({{ user.email }}). Pensez à vérifier vos spams si vous ne recevez pas l'email. En cas de problème, contactez le juge-arbitre.
{% endif %}
@@ -73,6 +90,9 @@
{% endif %}
{% if add_player_form.first_tournament or add_player_form.user_without_licence or tournament.license_is_required is False %}
{% if not add_player_form.user_without_licence and tournament.license_is_required is True %}
+
+ Padel Club n'a pas trouvé votre partenaire, il se peut qu'il s'agisse de son premier tournoi. Contacter le juge-arbitre après l'inscription si ce n'est pas le cas.
+
Précisez les informations du joueur :
diff --git a/tournaments/utils/player_search.py b/tournaments/utils/player_search.py
index 0f766ef..f8aeedd 100644
--- a/tournaments/utils/player_search.py
+++ b/tournaments/utils/player_search.py
@@ -9,7 +9,7 @@ from tournaments.models.enums import FederalCategory
def clean_licence_id(licence_id):
# This regex matches the trailing letters (non-digits) and removes them
cleaned_licence_id = re.sub(r'\D+$', '', str(licence_id)) # \D+ matches non-digits at the end
- return cleaned_licence_id
+ return cleaned_licence_id.lstrip("0")
def get_player_name_from_csv(category, licence_id, base_folder=None):
"""
@@ -29,6 +29,8 @@ def get_player_name_from_csv(category, licence_id, base_folder=None):
else:
cleaned_licence_id = None
+ print("get_player_name_from_csv", cleaned_licence_id)
+
def extract_date(file_name):
"""
Extract the date (MM-YYYY) from the file name and return it as a datetime object.
diff --git a/tournaments/views.py b/tournaments/views.py
index 5eefc8c..1f4e67a 100644
--- a/tournaments/views.py
+++ b/tournaments/views.py
@@ -170,7 +170,7 @@ def tournament_info(request, tournament_id):
stripped_license = validator.stripped_license
# Check if there is a PlayerRegistration for this user in this tournament
registered_user = PlayerRegistration.objects.filter(
- licence_id__startswith=stripped_license,
+ licence_id__icontains=stripped_license,
team_registration__tournament=tournament,
team_registration__walk_out=False,
).first()
@@ -747,7 +747,7 @@ def my_tournaments(request):
def filter_user_tournaments(tournaments):
return [t for t in tournaments if t.teamregistration_set.filter(
- playerregistration__licence_id__startswith=stripped_license,
+ playerregistration__licence_id__icontains=stripped_license,
walk_out=False
).exists()]
From 530a60b0e1bd319aec92c96258460fdb03a7fa74 Mon Sep 17 00:00:00 2001
From: Raz
Date: Sat, 8 Mar 2025 09:16:24 +0100
Subject: [PATCH 2/4] fix hide weight broadcast
---
.../templates/tournaments/broadcast/broadcasted_auto.html | 1 +
.../tournaments/broadcast/broadcasted_auto_event.html | 1 +
.../tournaments/broadcast/broadcasted_group_stage.html | 6 +++---
.../tournaments/broadcast/broadcasted_group_stages.html | 1 +
4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/tournaments/templates/tournaments/broadcast/broadcasted_auto.html b/tournaments/templates/tournaments/broadcast/broadcasted_auto.html
index a20e5fb..39545ef 100644
--- a/tournaments/templates/tournaments/broadcast/broadcasted_auto.html
+++ b/tournaments/templates/tournaments/broadcast/broadcasted_auto.html
@@ -38,6 +38,7 @@
paginatedSummons: null,
paginatedRankings: null,
active: 1,
+ hide_weight: {{ tournament.hide_weight|lower }},
prefixTitle: '',
retrieveData() {
fetch('/tournament/{{ tournament.id }}/broadcast/json/')
diff --git a/tournaments/templates/tournaments/broadcast/broadcasted_auto_event.html b/tournaments/templates/tournaments/broadcast/broadcasted_auto_event.html
index 2d63558..61153e4 100644
--- a/tournaments/templates/tournaments/broadcast/broadcasted_auto_event.html
+++ b/tournaments/templates/tournaments/broadcast/broadcasted_auto_event.html
@@ -39,6 +39,7 @@
paginatedSummons: null,
paginatedRankings: null,
active: 1,
+ hide_weight: {{ tournament.hide_weight|lower }},
prefixTitle: '',
eventTitle: '',
title: '',
diff --git a/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html b/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html
index 8c21269..48d7c68 100644
--- a/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html
+++ b/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html
@@ -31,9 +31,9 @@
- {% if not tournament.hide_weight %}
-
- {% endif %}
+
+
+
diff --git a/tournaments/templates/tournaments/broadcast/broadcasted_group_stages.html b/tournaments/templates/tournaments/broadcast/broadcasted_group_stages.html
index 69b7028..1d4171f 100644
--- a/tournaments/templates/tournaments/broadcast/broadcasted_group_stages.html
+++ b/tournaments/templates/tournaments/broadcast/broadcasted_group_stages.html
@@ -38,6 +38,7 @@
16:
+ # if more than 16 groupstage matches
+ now = timezone.now()
+ future_threshold = now + timedelta(hours=1)
+ past_threshold = now - timedelta(hours=1)
+ matches = [m for m in matches if m.should_appear() and
+ (m.start_date is None or m.start_date <= future_threshold) and # Not starting in more than 1h
+ (m.end_date is None or m.end_date >= past_threshold)] # Not finished for more than 1h
+ matches = matches[:16]
matches.sort(key=lambda m: (m.start_date is None, m.end_date is not None, m.start_date, m.index))
group_stage_loser_bracket = list(self.round_set.filter(parent=None, group_stage_loser_bracket=True).all())
diff --git a/tournaments/static/tournaments/css/broadcast.css b/tournaments/static/tournaments/css/broadcast.css
index ffd1f78..5171712 100644
--- a/tournaments/static/tournaments/css/broadcast.css
+++ b/tournaments/static/tournaments/css/broadcast.css
@@ -25,3 +25,57 @@ body {
.bold {
font-family: "Montserrat-Bold";
}
+
+.player {
+ position: relative;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 2.8em; /* This ensures minimum height for 2 lines */
+ justify-content: center;
+ overflow: hidden;
+}
+
+/* Add this if you want empty lines to take up space */
+.player div {
+ min-height: 1.4em; /* Height for single line */
+}
+
+/* For single player teams */
+.player.single-player .bold {
+ max-height: 2.8em; /* Adjust based on your needs */
+ line-height: 1.4em;
+ overflow: hidden;
+ position: relative;
+ text-overflow: ellipsis;
+}
+
+/* For two player teams */
+.player.two-players .bold {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.flex {
+ display: flex;
+ align-items: center;
+}
+
+.flex-left {
+ flex: 1;
+ text-align: left;
+ justify-content: center;
+ min-height: 4em;
+ padding-right: 5px;
+}
+
+.flex-right {
+ flex: initial;
+ text-align: right;
+ justify-content: center;
+}
+
+.center {
+ align-items: center;
+}
diff --git a/tournaments/static/tournaments/css/style.css b/tournaments/static/tournaments/css/style.css
index 035357a..80bcd9c 100644
--- a/tournaments/static/tournaments/css/style.css
+++ b/tournaments/static/tournaments/css/style.css
@@ -323,9 +323,34 @@ tr {
}
.player {
+ position: relative;
flex: 1;
display: flex;
flex-direction: column;
+ min-height: 2.8em; /* This ensures minimum height for 2 lines */
+ justify-content: center;
+ overflow: hidden;
+}
+
+/* Add this if you want empty lines to take up space */
+.player div {
+ min-height: 1.4em; /* Height for single line */
+}
+
+/* For single player teams */
+.player.single-player .semibold {
+ max-height: 2.8em; /* Adjust based on your needs */
+ line-height: 1.4em;
+ overflow: hidden;
+ position: relative;
+ text-overflow: ellipsis;
+}
+
+/* For two player teams */
+.player.two-players .semibold {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
.scores {
@@ -344,7 +369,6 @@ tr {
font-size: 1.3em;
vertical-align: middle;
text-align: center;
- padding: 0px 5px;
/* width: 30px; */
}
@@ -718,14 +742,15 @@ h-margin {
.flex-left {
flex: 1;
text-align: left;
- padding: 5px 0px;
+ justify-content: center;
+ min-height: 4em;
+ padding-right: 5px;
}
.flex-right {
flex: initial;
text-align: right;
- vertical-align: middle;
- padding: 5px 0px;
+ justify-content: center;
}
#header {
@@ -838,10 +863,6 @@ h-margin {
background-color: #90ee90; /* Light green color */
}
-.player {
- position: relative; /* Ensures the overlay is positioned within this block */
-}
-
.overlay-text {
position: absolute;
top: 50%;
diff --git a/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html b/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html
index 48d7c68..0d35253 100644
--- a/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html
+++ b/tournaments/templates/tournaments/broadcast/broadcasted_group_stage.html
@@ -8,7 +8,10 @@