from django.db import models from django.utils import timezone from . import TournamentSubModel, TeamRegistration, PlayerSexType, PlayerDataSource, PlayerPaymentType, OnlineRegistrationStatus, CustomUser from .enums import RegistrationStatus import uuid class PlayerRegistration(TournamentSubModel): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) team_registration = models.ForeignKey(TeamRegistration, on_delete=models.SET_NULL, related_name='player_registrations', null=True) user = models.ForeignKey(CustomUser, null=True, blank=True, on_delete=models.SET_NULL, related_name='player_registrations') first_name = models.CharField(max_length=50, blank=True) last_name = models.CharField(max_length=50, blank=True) licence_id = models.CharField(max_length=50, null=True, blank=True) rank = models.IntegerField(null=True, blank=True) #has_paid = models.BooleanField(default=False) #unranked = models.BooleanField(default=False) payment_type = models.IntegerField(choices=PlayerPaymentType.choices, null=True, blank=True) #registration_date = models.DateTimeField(null=True, blank=True) sex = models.IntegerField(choices=PlayerSexType.choices, null=True, blank=True) #donnee publique tournament_played = models.IntegerField(null=True, blank=True) points = models.FloatField(null=True, blank=True) club_name = models.CharField(max_length=200, null=True, blank=True) ligue_name = models.CharField(max_length=200, null=True, blank=True) assimilation = models.CharField(max_length=50, null=True, blank=True) club_code = models.CharField(max_length=20, null=True, blank=True) club_member = models.BooleanField(default=False) #beachpadel phone_number = models.CharField(max_length=50, null=True, blank=True) email = models.CharField(max_length=50, null=True, blank=True) birthdate = models.CharField(max_length=50, null=True, blank=True) computed_rank = models.IntegerField(default=0) source = models.IntegerField(choices=PlayerDataSource.choices, null=True, blank=True) has_arrived = models.BooleanField(default=False) captain = models.BooleanField(default=False) coach = models.BooleanField(default=False) registered_online = models.BooleanField(default=False) time_to_confirm = models.DateTimeField(null=True, blank=True) registration_status = models.IntegerField(choices=RegistrationStatus.choices, default=RegistrationStatus.WAITING) payment_id = models.CharField(max_length=255, blank=True, null=True) contact_phone_number = models.CharField(max_length=50, null=True, blank=True) contact_email = models.CharField(max_length=50, null=True, blank=True) contact_name = models.CharField(max_length=200, null=True, blank=True) is_anonymous = models.BooleanField(default=False) def delete_dependencies(self): pass def __str__(self): return self.name() def get_tournament(self): # mandatory method for TournamentSubModel if self.team_registration: return self.team_registration.tournament else: return None # def save(self, *args, **kwargs): # self.store_id = str(self.get_tournament_id()) # super().save(*args, **kwargs) # def get_tournament_id(self): # if self.team_registration and self.team_registration.tournament: # return self.team_registration.tournament.id # else: # return None def name(self): if self.is_anonymous: return "Joueur Anonyme" return f"{self.first_name} {self.last_name}" def shortened_name(self, forced=False): if self.is_anonymous: return "Anonyme" name = self.name() if (len(name) > 20 or forced) and self.first_name: if self.last_name is None: name = self.first_name elif self.first_name and len(self.first_name) > 0: name = f"{self.first_name[0]}. {self.last_name}" if len(name) > 20: name_parts = self.last_name.split(" ") if len(name_parts) > 0 and self.first_name and len(self.first_name) > 0: name = f"{self.first_name[0]}. {name_parts[0]}" return name def clean_club_name(self): if self.is_anonymous: return "Anonyme" if self.club_name: return self.club_name.split(' (')[0] return "Non renseigné" def calculate_age(self): if self.is_anonymous: return None if self.birthdate: try: birth_year = int(self.birthdate[-4:]) # Assumes birthdate ends with YYYY current_year = timezone.now().year return current_year - birth_year except (ValueError, TypeError, IndexError): return None return None def format_ordinal(self): if self.rank is None: if self.sex == PlayerSexType.FEMALE: return "Non Classée" return "Non Classé" if self.rank == 1: if self.sex == PlayerSexType.FEMALE: return "1ère" return "1er" return f"{self.rank}ème" def get_registration_status(self): """ Returns a status object with information about the player's registration status. This object contains display_box, box_class, and short_label properties used in the tournament row template. Returns None if no relevant status can be determined. """ # If no team registration exists, return None if not self.team_registration: return None tournament = self.team_registration.tournament tournament_status_team_count = tournament.get_tournament_status_registration_count() # If custom animation type, replace header by "Inscriptions" if tournament.is_team_tournament(): header = "Équipes" else: header = "Inscriptions" if tournament.is_canceled(): return { 'header': header, 'position': tournament_status_team_count, 'is_team_tournament': tournament.is_team_tournament(), 'display_box': True, 'box_class': 'light-red', 'short_label': 'annulé' } status = { 'header': header, 'position': tournament_status_team_count, 'is_team_tournament': True, 'display_box': True, 'box_class': 'gray', 'short_label': 'inscrit' } team = self.team_registration # Tournament is ended with results if tournament.get_online_registration_status() is OnlineRegistrationStatus.ENDED_WITH_RESULTS: if team.final_ranking: status['header'] = 'Rang' status['position'] = f"{team.final_ranking} / {tournament_status_team_count}" if tournament.display_points_earned and team.points_earned: if team.final_ranking == 1: status['box_class'] = 'light-gold' elif team.final_ranking == 2: status['box_class'] = 'light-silver' elif team.final_ranking == 3: status['box_class'] = 'light-bronze' else: status['box_class'] = 'light-beige' status['short_label'] = f"{team.points_earned} pts" else: status['display_box'] = False return status # Team has walked out if team.walk_out: status['box_class'] = 'light-red' status['short_label'] = 'forfait' return status # Tournament is in progress if tournament.supposedly_in_progress(): status['box_class'] = 'light-green' status['short_label'] = 'en lice' return status # Tournament hasn't started yet if team.is_in_waiting_list() >= 0: status['box_class'] = 'light-yellow' status['short_label'] = "en attente" else: status['box_class'] = 'light-green' status['short_label'] = 'inscrit' return status def has_paid(self): return self.payment_type is not None def get_remaining_fee(self): if self.has_paid(): return 0 if self.club_member and self.team_registration.tournament.club_member_fee_deduction is not None and self.team_registration.tournament.entry_fee is not None: return self.team_registration.tournament.entry_fee - self.team_registration.tournament.club_member_fee_deduction elif self.team_registration.tournament.entry_fee is not None: return self.team_registration.tournament.entry_fee elif self.team_registration.tournament.club_member_fee_deduction is not None: return self.team_registration.tournament.club_member_fee_deduction else: return 0 def get_player_registration_fee(self): if self.club_member and self.team_registration.tournament.club_member_fee_deduction is not None and self.team_registration.tournament.entry_fee is not None: return self.team_registration.tournament.entry_fee - self.team_registration.tournament.club_member_fee_deduction elif self.team_registration.tournament.entry_fee is not None: return self.team_registration.tournament.entry_fee else: return 0 def player_contact(self): if self.contact_email: return self.contact_email return self.email def get_last_name(self): if self.is_anonymous: return "Anonyme" return self.last_name