@ -1,3 +1,4 @@
from zoneinfo import ZoneInfo
from django . db import models
from django . db import models
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING
if TYPE_CHECKING :
if TYPE_CHECKING :
@ -7,6 +8,8 @@ from . import Event, TournamentPayment, FederalMatchCategory, FederalCategory, F
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
from zoneinfo import ZoneInfo
from shared . cryptography import encryption_util
from shared . cryptography import encryption_util
from . . utils . extensions import plural_format
from . . utils . extensions import plural_format
@ -129,6 +132,19 @@ class Tournament(models.Model):
components . append ( self . name )
components . append ( self . name )
return ( ' ' ) . join ( components )
return ( ' ' ) . join ( components )
def timezone ( self ) :
tz = ' CET '
if self . event and self . event . club :
tz = self . event . club . timezone
return ZoneInfo ( tz )
def local_start_date ( self ) :
timezone = self . timezone ( )
return self . start_date . astimezone ( timezone )
def local_start_date_formatted ( self ) :
return formats . date_format ( self . local_start_date ( ) , format = ' j F Y H:i ' )
def level ( self ) :
def level ( self ) :
if self . federal_level_category == 0 :
if self . federal_level_category == 0 :
return " Anim. "
return " Anim. "
@ -216,6 +232,7 @@ class Tournament(models.Model):
def team_summons ( self ) :
def team_summons ( self ) :
summons = [ ]
summons = [ ]
print ( ' >>> team_summons ' )
if self . supposedly_in_progress ( ) and self . end_date is None :
if self . supposedly_in_progress ( ) and self . end_date is None :
for team in self . teams ( False ) :
for team in self . teams ( False ) :
names = team . names
names = team . names
@ -231,7 +248,7 @@ class Tournament(models.Model):
names = team_registration . team_names ( )
names = team_registration . team_names ( )
stage = next_match . summon_stage_name ( )
stage = next_match . summon_stage_name ( )
weight = team_registration . weight
weight = team_registration . weight
summon = TeamSummon ( names , next_match . start_date , weight , stage , next_match . court_name ( next_match . court_index ) , team_registration . logo )
summon = TeamSummon ( names , next_match . local_ start_date( ) , weight , stage , next_match . court_name ( next_match . court_index ) , team_registration . logo )
summons . append ( summon )
summons . append ( summon )
summons . sort ( key = lambda s : ( s . date is None , s . date or datetime . min ) )
summons . sort ( key = lambda s : ( s . date is None , s . date or datetime . min ) )
@ -259,7 +276,7 @@ class Tournament(models.Model):
return rankings
return rankings
def teams ( self , includeWaitingList ) :
def teams ( self , includeWaitingList ) :
print ( " Starting teams method " )
# print("Starting teams method" )
bracket_teams = [ ]
bracket_teams = [ ]
group_stage_teams = [ ]
group_stage_teams = [ ]
waiting_teams = [ ]
waiting_teams = [ ]
@ -268,10 +285,10 @@ class Tournament(models.Model):
wildcard_group_stage = [ ]
wildcard_group_stage = [ ]
complete_teams = [ ]
complete_teams = [ ]
closed_registration_date = self . closed_registration_date
closed_registration_date = self . closed_registration_date
print ( f " Closed registration date: { closed_registration_date } " )
# print(f"Closed registration date: {closed_registration_date}" )
for team_registration in self . teamregistration_set . all ( ) :
for team_registration in self . teamregistration_set . all ( ) :
print ( f " Processing team registration: { team_registration } " )
# print(f"Processing team registration: {team_registration}" )
is_valid = False
is_valid = False
if closed_registration_date is not None and team_registration . registration_date is not None and team_registration . registration_date < = closed_registration_date :
if closed_registration_date is not None and team_registration . registration_date is not None and team_registration . registration_date < = closed_registration_date :
is_valid = True
is_valid = True
@ -279,7 +296,7 @@ class Tournament(models.Model):
is_valid = True
is_valid = True
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 . walk_out is False :
if team_registration . walk_out is False :
names = team_registration . team_names ( )
names = team_registration . team_names ( )
@ -287,14 +304,14 @@ class Tournament(models.Model):
initial_weight = team_registration . initial_weight ( )
initial_weight = team_registration . initial_weight ( )
date = team_registration . call_date
date = team_registration . call_date
team = TeamList ( names , weight , date , initial_weight , team_registration . wild_card_bracket , team_registration . wild_card_group_stage , team_registration . logo )
team = TeamList ( names , weight , date , initial_weight , team_registration . wild_card_bracket , team_registration . wild_card_group_stage , team_registration . logo )
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 :
team . set_stage ( " Poule " )
team . set_stage ( " Poule " )
elif team_registration . bracket_position is not None :
elif team_registration . bracket_position is not None :
team . set_stage ( " Tableau " )
team . set_stage ( " Tableau " )
else :
else :
team . set_stage ( " Attente " )
team . set_stage ( " Attente " )
print ( f " Team stage: { team . stage } " )
# print(f"Team stage: {team.stage}" )
teams . append ( team )
teams . append ( team )
if team_registration . wild_card_bracket :
if team_registration . wild_card_bracket :
@ -306,11 +323,11 @@ class Tournament(models.Model):
else :
else :
waiting_teams . append ( team )
waiting_teams . append ( team )
print ( f " Total teams: { len ( teams ) } " )
# print(f"Total teams: {len(teams)}" )
print ( f " Wildcard bracket: { len ( wildcard_bracket ) } " )
# print(f"Wildcard bracket: {len(wildcard_bracket)}" )
print ( f " Wildcard group stage: { len ( wildcard_group_stage ) } " )
# print(f"Wildcard group stage: {len(wildcard_group_stage)}" )
print ( f " Complete teams: { len ( complete_teams ) } " )
# print(f"Complete teams: {len(complete_teams)}" )
print ( f " Waiting teams: { len ( waiting_teams ) } " )
# print(f"Waiting teams: {len(waiting_teams)}" )
if len ( teams ) < self . team_count :
if len ( teams ) < self . team_count :
teams . sort ( key = lambda s : ( s . initial_weight , s . date ) )
teams . sort ( key = lambda s : ( s . initial_weight , s . date ) )
@ -323,8 +340,8 @@ class Tournament(models.Model):
group_stage_members_count = 0
group_stage_members_count = 0
if seeds_count < 0 :
if seeds_count < 0 :
seeds_count = 0
seeds_count = 0
print ( f " Seeds count: { seeds_count } " )
# print(f"Seeds count: {seeds_count}" )
print ( f " Group stage members count: { group_stage_members_count } " )
# print(f"Group stage members count: {group_stage_members_count}" )
if self . team_sorting == TeamSortingType . INSCRIPTION_DATE :
if self . team_sorting == TeamSortingType . INSCRIPTION_DATE :
complete_teams . sort ( key = lambda s : ( s . date is None , s . date or datetime . min , s . initial_weight ) )
complete_teams . sort ( key = lambda s : ( s . date is None , s . date or datetime . min , s . initial_weight ) )
@ -333,25 +350,25 @@ class Tournament(models.Model):
selected_teams = complete_teams [ : self . team_count ]
selected_teams = complete_teams [ : self . team_count ]
selected_teams . sort ( key = lambda s : s . initial_weight )
selected_teams . sort ( key = lambda s : s . initial_weight )
print ( f " Selected teams: { len ( selected_teams ) } " )
# print(f"Selected teams: {len(selected_teams)}" )
if seeds_count > 0 :
if seeds_count > 0 :
bracket_teams = selected_teams [ : seeds_count ] + wildcard_bracket
bracket_teams = selected_teams [ : seeds_count ] + wildcard_bracket
else :
else :
bracket_teams = [ ]
bracket_teams = [ ]
print ( f " Bracket teams: { len ( bracket_teams ) } " )
# print(f"Bracket teams: {len(bracket_teams)}" )
if group_stage_members_count :
if group_stage_members_count :
group_stage_end = seeds_count + group_stage_members_count
group_stage_end = seeds_count + group_stage_members_count
group_stage_teams = selected_teams [ seeds_count : group_stage_end ] + wildcard_group_stage
group_stage_teams = selected_teams [ seeds_count : group_stage_end ] + wildcard_group_stage
else :
else :
group_stage_teams = [ ]
group_stage_teams = [ ]
print ( f " Group stage teams: { len ( group_stage_teams ) } " )
# print(f"Group stage teams: {len(group_stage_teams)}" )
waiting_list_count = len ( teams ) - self . team_count
waiting_list_count = len ( teams ) - self . team_count
if waiting_list_count < 0 :
if waiting_list_count < 0 :
waiting_list_count = 0
waiting_list_count = 0
print ( f " Waiting list count: { waiting_list_count } " )
# print(f"Waiting list count: {waiting_list_count}" )
if waiting_list_count > 0 or len ( waiting_teams ) > 0 :
if waiting_list_count > 0 or len ( waiting_teams ) > 0 :
if waiting_list_count > 0 :
if waiting_list_count > 0 :
@ -362,7 +379,7 @@ class Tournament(models.Model):
waiting_teams . sort ( key = lambda s : ( s . initial_weight , s . date ) )
waiting_teams . sort ( key = lambda s : ( s . initial_weight , s . date ) )
else :
else :
waiting_teams = [ ]
waiting_teams = [ ]
print ( f " Final waiting teams: { len ( waiting_teams ) } " )
# print(f"Final waiting teams: {len(waiting_teams)}" )
bracket_teams . sort ( key = lambda s : s . weight )
bracket_teams . sort ( key = lambda s : s . weight )
group_stage_teams . sort ( key = lambda s : s . weight )
group_stage_teams . sort ( key = lambda s : s . weight )
@ -380,10 +397,10 @@ class Tournament(models.Model):
if includeWaitingList is True :
if includeWaitingList is True :
final_teams = bracket_teams + group_stage_teams + waiting_teams
final_teams = bracket_teams + group_stage_teams + waiting_teams
print ( f " Final teams with waiting list: { len ( final_teams ) } " )
# print(f"Final teams with waiting list: {len(final_teams)}" )
else :
else :
final_teams = bracket_teams + group_stage_teams
final_teams = bracket_teams + group_stage_teams
print ( f " Final teams without waiting list: { len ( final_teams ) } " )
# print(f"Final teams without waiting list: {len(final_teams)}" )
return final_teams
return final_teams
@ -791,8 +808,23 @@ class Tournament(models.Model):
return date . replace ( hour = 8 , minute = 0 , second = 0 , microsecond = 0 , tzinfo = date . tzinfo )
return date . replace ( hour = 8 , minute = 0 , second = 0 , microsecond = 0 , tzinfo = date . tzinfo )
def supposedly_in_progress ( self ) :
def supposedly_in_progress ( self ) :
end = self . start_date + timedelta ( days = self . day_duration + 1 )
# end = self.start_date + timedelta(days=self.day_duration + 1)
return self . start_date . replace ( hour = 0 , minute = 0 ) < = timezone . now ( ) < = end
# return self.start_date.replace(hour=0, minute=0) <= timezone.now() <= end
timezoned_datetime = timezone . localtime ( self . start_date )
end = timezoned_datetime + timedelta ( days = self . day_duration + 1 )
now = timezone . now ( )
start = timezoned_datetime . replace ( hour = 0 , minute = 0 )
print ( f " timezoned_datetime: { timezoned_datetime } " )
print ( f " tournament end date: { end } " )
print ( f " current time: { now } " )
print ( f " tournament start: { start } " )
print ( f " start <= now <= end: { start < = now < = end } " )
return start < = now < = end
def display_points_earned ( self ) :
def display_points_earned ( self ) :
return self . federal_level_category != FederalLevelCategory . UNLISTED and self . hide_points_earned is False
return self . federal_level_category != FederalLevelCategory . UNLISTED and self . hide_points_earned is False
@ -840,10 +872,9 @@ class TeamSummon:
def formatted_date ( self ) :
def formatted_date ( self ) :
if self . date :
if self . date :
timezoned_datetime = timezone . localtime ( self . date )
return formats . date_format ( self . date , format = ' l H:i ' )
return formats . date_format ( timezoned_datetime , format = ' l H:i ' )
else :
else :
return None
return ' '
def to_dict ( self ) :
def to_dict ( self ) :
return {
return {