improve online register

online_registration
Raz 11 months ago
parent 6ee05d58bd
commit e5cc96bae6
  1. 28
      tournaments/migrations/0100_playerregistration_coach_and_more.py
  2. 2
      tournaments/models/__init__.py
  3. 26
      tournaments/models/enums.py
  4. 1
      tournaments/models/player_registration.py
  5. 6
      tournaments/models/team_registration.py
  6. 116
      tournaments/models/tournament.py
  7. 40
      tournaments/templates/tournaments/tournament_info.html
  8. 6
      tournaments/templates/tournaments/tournament_row.html
  9. 3
      tournaments/views.py

@ -0,0 +1,28 @@
# Generated by Django 4.2.11 on 2024-12-10 08:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tournaments', '0099_remove_tournament_display_entry_fee_information'),
]
operations = [
migrations.AddField(
model_name='playerregistration',
name='coach',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='teamregistration',
name='unregistered',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='teamregistration',
name='unregistration_date',
field=models.DateTimeField(blank=True, null=True),
),
]

@ -2,7 +2,7 @@ from .custom_user import CustomUser
from .club import Club from .club import Club
from .court import Court from .court import Court
from .date_interval import DateInterval from .date_interval import DateInterval
from .enums import TournamentPayment, FederalCategory, FederalLevelCategory, FederalAgeCategory, FederalMatchCategory from .enums import TournamentPayment, FederalCategory, FederalLevelCategory, FederalAgeCategory, FederalMatchCategory, OnlineRegistrationStatus
from .player_enums import PlayerSexType, PlayerDataSource, PlayerPaymentType from .player_enums import PlayerSexType, PlayerDataSource, PlayerPaymentType
from .event import Event from .event import Event
from .tournament import Tournament, TeamSummon, TeamSortingType, TeamItem from .tournament import Tournament, TeamSummon, TeamSortingType, TeamItem

@ -85,3 +85,29 @@ class FederalMatchCategory(models.IntegerChoices):
return 1 return 1
else: else:
return 3 return 3
class OnlineRegistrationStatus(models.IntegerChoices):
OPEN = 1, 'Open'
NOT_ENABLED = 2, 'Not Enabled'
NOT_STARTED = 3, 'Not Started'
ENDED = 4, 'Ended'
REGISTRATION_FULL = 5, 'Registration Full'
WAITING_LIST_POSSIBLE = 6, 'Waiting List Possible'
WAITING_LIST_FULL = 7, 'Waiting List Full'
IN_PROGRESS = 8, 'In Progress'
ENDED_WITH_RESULTS = 9, 'Ended with Results'
def status_localized(self) -> str:
status_map = {
OnlineRegistrationStatus.OPEN: "Inscription ouverte",
OnlineRegistrationStatus.NOT_ENABLED: "Inscription désactivée",
OnlineRegistrationStatus.NOT_STARTED: "Inscription pas encore ouverte",
OnlineRegistrationStatus.ENDED: "Inscription terminée",
OnlineRegistrationStatus.REGISTRATION_FULL: "Inscription complète",
OnlineRegistrationStatus.WAITING_LIST_POSSIBLE: "Liste d'attente disponible",
OnlineRegistrationStatus.WAITING_LIST_FULL: "Liste d'attente complète",
OnlineRegistrationStatus.IN_PROGRESS: "Tournoi en cours",
OnlineRegistrationStatus.ENDED_WITH_RESULTS: "Tournoi terminé"
}
return status_map.get(self, "")

@ -34,6 +34,7 @@ class PlayerRegistration(models.Model):
source = models.IntegerField(choices=PlayerDataSource.choices, null=True, blank=True) source = models.IntegerField(choices=PlayerDataSource.choices, null=True, blank=True)
has_arrived = models.BooleanField(default=False) has_arrived = models.BooleanField(default=False)
captain = models.BooleanField(default=False) captain = models.BooleanField(default=False)
coach = models.BooleanField(default=False)
def __str__(self): def __str__(self):
return self.name() return self.name()

@ -29,7 +29,8 @@ class TeamRegistration(models.Model):
final_ranking = models.IntegerField(null=True, blank=True) final_ranking = models.IntegerField(null=True, blank=True)
points_earned = models.IntegerField(null=True, blank=True) points_earned = models.IntegerField(null=True, blank=True)
unregistered = models.BooleanField(default=False)
unregistration_date = models.DateTimeField(null=True, blank=True)
def __str__(self): def __str__(self):
if self.name: if self.name:
@ -115,3 +116,6 @@ class TeamRegistration(models.Model):
else: else:
# print("no date") # print("no date")
return None return None
def out_of_tournament(self):
return self.walk_out or self.unregistered

@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from tournaments.models import group_stage from tournaments.models import group_stage
from . import Event, TournamentPayment, FederalMatchCategory, FederalCategory, FederalLevelCategory, FederalAgeCategory from . import Event, TournamentPayment, FederalMatchCategory, FederalCategory, FederalLevelCategory, FederalAgeCategory, OnlineRegistrationStatus
import uuid import uuid
from django.utils import timezone, formats from django.utils import timezone, formats
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -219,12 +219,19 @@ class Tournament(models.Model):
return f"{len(teams)} {word}" return f"{len(teams)} {word}"
else: else:
return None return None
registration_status = None
if self.online_register_is_enabled() is True:
registration_status = self.get_online_registration_status().status_localized()
if teams is not None and len(teams) > 0: if teams is not None and len(teams) > 0:
word = "inscription" word = "inscription"
if len(teams) > 1: if len(teams) > 1:
word = word + "s" word = word + "s"
return f"{len(teams)} {word}" if registration_status is not None:
return f"{registration_status}\n{len(teams)} {word}"
else: else:
if registration_status is not None:
return f"{registration_status}"
return None return None
def name_and_event(self): def name_and_event(self):
@ -277,6 +284,7 @@ class Tournament(models.Model):
def rankings(self): def rankings(self):
rankings = [] rankings = []
for team_registration in self.teamregistration_set.all(): for team_registration in self.teamregistration_set.all():
if team_registration.walk_out is False and team_registration.final_ranking is not None: if team_registration.walk_out is False and team_registration.final_ranking is not None:
names = team_registration.team_names() names = team_registration.team_names()
ranking = team_registration.final_ranking ranking = team_registration.final_ranking
@ -309,8 +317,7 @@ class Tournament(models.Model):
if team_registration.registration_date is None: if team_registration.registration_date is None:
is_valid = True is_valid = True
# print(f"Is valid: {is_valid}") # print(f"Is valid: {is_valid}")
if team_registration.out_of_tournament() is False:
if team_registration.walk_out is False:
team = TeamItem(team_registration) team = TeamItem(team_registration)
# print(f"Created team: {team}") # print(f"Created team: {team}")
if team_registration.group_stage_position is not None: if team_registration.group_stage_position is not None:
@ -880,28 +887,117 @@ class Tournament(models.Model):
return False return False
return True return True
def options_online_registration(self):
options = []
# Date d'ouverture
if self.opening_registration_date:
date = formats.date_format(self.opening_registration_date, format='j F Y H:i')
options.append(f"Ouverture des inscriptions le {date}")
# Date limite
if self.registration_date_limit:
date = formats.date_format(self.registration_date_limit, format='j F Y H:i')
options.append(f"Clôture des inscriptions le {date}")
# Cible d'équipes
if self.target_team_count:
options.append(f"Maximum {self.target_team_count} équipes")
# Liste d'attente
if self.waiting_list_limit:
options.append(f"Liste d'attente limitée à {self.waiting_list_limit} équipes")
# Options d'inscription
if self.account_is_required:
options.append("Compte requis")
if self.license_is_required:
options.append("Licence requise")
# Joueurs par équipe
min_players = self.minimum_player_per_team
max_players = self.maximum_player_per_team
if min_players == max_players:
options.append(f"{min_players} joueurs par équipe")
else:
options.append(f"Entre {min_players} et {max_players} joueurs par équipe")
return options
def online_register_is_enabled(self): def online_register_is_enabled(self):
if self.supposedly_in_progress(): if self.supposedly_in_progress():
return False return False
if self.end_date is not None: if self.end_date is not None:
return False return False
now = datetime.now() now = timezone.now()
# Check if online registration is enabled # Check if online registration is enabled
if not self.enable_online_registration: if not self.enable_online_registration:
return False return False
# Check opening registration date # Check opening registration date
if self.opening_registration_date is not None and now < self.opening_registration_date: if self.opening_registration_date is not None:
return False timezoned_datetime = timezone.localtime(self.opening_registration_date)
if now < timezoned_datetime:
return False
# Check registration date limit # Check registration date limit
if self.registration_date_limit is not None and now > self.registration_date_limit: if self.registration_date_limit is not None:
return False timezoned_datetime = timezone.localtime(self.registration_date_limit)
if now > timezoned_datetime:
return False
# All conditions are satisfied # Check target team count and waiting list limit
if self.target_team_count is not None:
current_team_count = len([tr for tr in self.teamregistration_set.all() if tr.out_of_tournament() is False])
if current_team_count >= self.target_team_count:
if self.waiting_list_limit is not None:
waiting_list_count = current_team_count - self.target_team_count
if waiting_list_count >= self.waiting_list_limit:
return False
return True return True
def get_online_registration_status(self):
if self.supposedly_in_progress():
return OnlineRegistrationStatus.IN_PROGRESS
if self.end_date is not None:
return OnlineRegistrationStatus.ENDED_WITH_RESULTS
now = timezone.now()
if self.opening_registration_date is not None:
timezoned_datetime = timezone.localtime(self.opening_registration_date)
if now < timezoned_datetime:
return OnlineRegistrationStatus.NOT_STARTED
if self.registration_date_limit is not None:
timezoned_datetime = timezone.localtime(self.registration_date_limit)
if now > timezoned_datetime:
return OnlineRegistrationStatus.ENDED
if self.target_team_count is not None:
# Get all team registrations excluding walk_outs
current_team_count = len([tr for tr in self.teamregistration_set.all() if tr.out_of_tournament() is False])
if current_team_count >= self.target_team_count:
if self.waiting_list_limit is not None:
waiting_list_count = current_team_count - self.target_team_count
if waiting_list_count >= self.waiting_list_limit:
return OnlineRegistrationStatus.WAITING_LIST_FULL
return OnlineRegistrationStatus.WAITING_LIST_POSSIBLE
return OnlineRegistrationStatus.REGISTRATION_FULL
current_team_count = self.teamregistration_set.filter(walk_out=False).count()
if current_team_count >= self.target_team_count:
if self.waiting_list_limit is not None:
waiting_list_count = current_team_count - self.target_team_count
if waiting_list_count >= self.waiting_list_limit:
return OnlineRegistrationStatus.WAITING_LIST_FULL
return OnlineRegistrationStatus.WAITING_LIST_POSSIBLE
return OnlineRegistrationStatus.REGISTRATION_FULL
return OnlineRegistrationStatus.OPEN
class MatchGroup: class MatchGroup:
def __init__(self, name, matches, formatted_schedule): def __init__(self, name, matches, formatted_schedule):
self.name = name self.name = name

@ -48,23 +48,37 @@
{% if tournament.online_register_is_enabled %} {% if tournament.online_register_is_enabled %}
<p> <p>
<div class="semibold">Statut</div> <div class="semibold">Inscription en ligne</div>
{% if tournament.registration_count_display %}
<div>{{ tournament.registration_count_display }}</div> {% if tournament.options_online_registration %}
{% else %} <ul>
<div>Aucune équipe inscrite</div> {% for option in tournament.options_online_registration %}
<li>{{ option }}</li>
{% endfor %}
</ul>
{% endif %} {% endif %}
</p> </p>
{% endif %}
{% if tournament.online_register_is_enabled and team is None %} <p>
<div class="semibold">
{% if tournament.registration_count_display %}
<div>{{ tournament.registration_count_display }}</div>
{% else %}
<div>Aucune équipe inscrite</div>
{% endif %}
</div>
</p>
<p> <p>
<div class="semibold"> <div class="semibold">
L'inscription en ligne est possible. {{ tournament.get_online_registration_status.status_localized }}
</div> </div>
</p> </p>
{% 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 tournament.account_is_required is False or user.is_authenticated and user.is_active %}
<p> <p>
@ -114,7 +128,7 @@
<div>Inscrit le {{ team.registration_date }}</div> <div>Inscrit le {{ team.registration_date }}</div>
</p> </p>
{% if is_captain %}
<p> <p>
<a href="{% url 'unregister_tournament' tournament.id %}" <a href="{% url 'unregister_tournament' tournament.id %}"
class="rounded-button destructive-button" class="rounded-button destructive-button"
@ -122,10 +136,12 @@
Se désinscrire Se désinscrire
</a> </a>
</p> </p>
<!-- {% if is_captain %}
{% else %} {% else %}
<p> <p>
<div>Vous n'êtes pas le capitaine de l'équipe, la désinscription en ligne n'est pas disponible. Veuillez contacter le JAP ou votre partenaire.</div> <div>Vous n'êtes pas le capitaine de l'équipe, la désinscription en ligne n'est pas disponible. Veuillez contacter le JAP ou votre partenaire.</div>
</p> </p> -->
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}

@ -26,12 +26,14 @@
</div> </div>
{% if tournament.tournament_status_display %} {% if tournament.tournament_status_display %}
<div class="table-cell-responsive-large center horizontal-padding">{{ tournament.tournament_status_display }}</div> <div class="table-cell-responsive-large center horizontal-padding">
{{ tournament.tournament_status_display|linebreaksbr }}
</div>
{% endif %} {% endif %}
<div class="table-cell"> <div class="table-cell">
<div class="mybox center">{{ tournament.formatted_start_date }}</div> <div class="mybox center">{{ tournament.formatted_start_date }}</div>
{% if tournament.tournament_status_display %} {% if tournament.tournament_status_display %}
<div class="table-cell-responsive-short small center">{{ tournament.tournament_status_display }}</div> <div class="table-cell-responsive-short small center">{{ tournament.tournament_status_display|linebreaksbr }}</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>

@ -852,6 +852,9 @@ def unregister_tournament(request, tournament_id):
def validate_license_id(licence_id, tournament): def validate_license_id(licence_id, tournament):
teams = TeamRegistration.objects.filter(tournament=tournament) teams = TeamRegistration.objects.filter(tournament=tournament)
# Filter out walkouts and unregistered teams
teams = teams.filter(walk_out=False, unregistered=False)
# Check if any player in any team in the tournament already has this licence_id # Check if any player in any team in the tournament already has this licence_id
# Normalize the licence ID before querying # Normalize the licence ID before querying
# Loop through each team and check if any of its players has the same licence_id # Loop through each team and check if any of its players has the same licence_id

Loading…
Cancel
Save