from background_task import background from django.utils import timezone from django.db import transaction from django.conf import settings from .models import PlayerRegistration from .models.enums import RegistrationStatus from .services.email_service import TournamentEmailService, TeamEmailType @background(schedule=settings.BACKGROUND_SCHEDULED_TASK_INTERVAL * 60) # Run every 30 minutes (30*60 seconds) def background_task_check_confirmation_deadlines(): #DEBUG ONLY NOT NEEDED ON PROD print("background_task Running confirmation deadline check...") check_confirmation_deadlines() def check_confirmation_deadlines(): """ Periodic task to check for expired confirmation deadlines and notify the next team in the waiting list. """ now = timezone.now() print(f"[{now}] Running confirmation deadline check...") # Find players with expired confirmation deadlines expired_confirmations = PlayerRegistration.objects.filter( registration_status=RegistrationStatus.PENDING, registered_online=True, team_registration__isnull=False ).select_related('team_registration', 'team_registration__tournament') print(f"Found {expired_confirmations.count()} expired confirmations") # Process each expired confirmation processed_teams = set() # To avoid processing the same team multiple times for player in expired_confirmations: team_registration = player.team_registration # Skip if we've already processed this team if team_registration.id in processed_teams: continue processed_teams.add(team_registration.id) tournament = team_registration.tournament if not tournament or not tournament.automatic_waiting_list(): continue teams = tournament.teams(True) waiting_list_teams = tournament.waiting_list_teams(teams) if waiting_list_teams is not None: ttc = tournament.calculate_time_to_confirm(len(waiting_list_teams)) else: ttc = None first_waiting_list_team = tournament.first_waiting_list_team(teams) # Process in a transaction to ensure atomic operations with transaction.atomic(): # Get all players in this team and mark them as expired team_players = PlayerRegistration.objects.filter( team_registration=team_registration, registered_online=True ) should_update_team = False should_send_mail = False for team_player in team_players: if team_player.time_to_confirm is None and first_waiting_list_team is not None: team_registration.set_time_to_confirm(ttc) team_player.save() should_send_mail = True print(team_player, "team_player.time_to_confirm is None and", ttc) elif team_player.time_to_confirm is not None and now > team_player.time_to_confirm: team_player.registration_status = RegistrationStatus.CANCELED team_player.time_to_confirm = None team_player.save() team_registration.registration_date = now print(team_player, "time_to_confirm = ", team_player.time_to_confirm) should_update_team = True # elif team_player.time_to_confirm is not None and team_player.time_to_confirm > ttc: # team_player.registration_status = RegistrationStatus.PENDING # team_player.time_to_confirm = ttc # team_player.save() # should_update_team = True if should_send_mail: TournamentEmailService.notify_team( team_registration, tournament, TeamEmailType.OUT_OF_WAITING_LIST ) if should_update_team: team_registration.save() print(f"Team {team_registration} confirmation expired in tournament {tournament.id}")