diff --git a/tournaments/models/tournament.py b/tournaments/models/tournament.py index 6ca06b1..d0f202a 100644 --- a/tournaments/models/tournament.py +++ b/tournaments/models/tournament.py @@ -1073,6 +1073,8 @@ class Tournament(BaseModel): options.append(f"Remboursement possible jusqu'au {date}") elif self.enable_online_payment_refund: options.append("Remboursement possible") + else: + options.append("Remboursement impossible") # Joueurs par équipe min_players = self.minimum_player_per_team @@ -1175,7 +1177,7 @@ class Tournament(BaseModel): return -1 # Get count of active teams (not walked out) - current_team_count = self.team_registrations.exclude(walk_out=True).count() + current_team_count = self.team_registrations.exclude(walk_out=True).count() + self.reserved_spots # If current count is less than target count, next team is not in waiting list if current_team_count < self.team_count: @@ -1731,7 +1733,6 @@ class Tournament(BaseModel): return False def is_refund_possible(self): - return True if self.enable_online_payment_refund: time = timezone.now() if self.refund_date_limit: diff --git a/tournaments/services/tournament_registration.py b/tournaments/services/tournament_registration.py index f8c13dc..a019583 100644 --- a/tournaments/services/tournament_registration.py +++ b/tournaments/services/tournament_registration.py @@ -12,7 +12,7 @@ class RegistrationCartManager: and checkout processes. """ - CART_EXPIRY_MINUTES = 30 + CART_EXPIRY_SECONDS = 300 def __init__(self, request): self.request = request @@ -29,7 +29,7 @@ class RegistrationCartManager: """Get the cart expiry time from the session""" if 'registration_cart_expiry' not in self.session: # Set default expiry to 30 minutes from now - expiry = timezone.now() + datetime.timedelta(minutes=self.CART_EXPIRY_MINUTES) + expiry = timezone.now() + datetime.timedelta(seconds=self.CART_EXPIRY_SECONDS) self.session['registration_cart_expiry'] = expiry.isoformat() self.session.modified = True return self.session['registration_cart_expiry'] @@ -48,7 +48,7 @@ class RegistrationCartManager: def reset_cart_expiry(self): """Reset the cart expiry time""" - expiry = timezone.now() + datetime.timedelta(minutes=self.CART_EXPIRY_MINUTES) + expiry = timezone.now() + datetime.timedelta(seconds=self.CART_EXPIRY_SECONDS) self.session['registration_cart_expiry'] = expiry.isoformat() self.session.modified = True @@ -69,12 +69,7 @@ class RegistrationCartManager: # Update tournament reserved spots tournament.reserved_spots = max(0, tournament.reserved_spots - 1) waiting_list_position = tournament.get_waiting_list_position() - - if waiting_list_position >= 0: - tournament.reserved_spots = 0 - else: - tournament.reserved_spots += 1 - + tournament.reserved_spots += 1 tournament.save() # Set up the new cart @@ -107,12 +102,25 @@ class RegistrationCartManager: if hasattr(self.request.user, 'phone'): user_phone = self.request.user.phone + # Parse the expiry time from ISO format to datetime + expiry_str = self.get_cart_expiry() + expiry_datetime = None + if expiry_str: + try: + # Parse the ISO format string to datetime + from django.utils.dateparse import parse_datetime + expiry_datetime = parse_datetime(expiry_str) + except (ValueError, TypeError): + # If parsing fails, set a new expiry + expiry_datetime = timezone.now() + datetime.timedelta(seconds=self.CART_EXPIRY_SECONDS) + cart_data = { 'cart_id': self.get_or_create_cart_id(), 'tournament_id': self.session.get('registration_tournament_id'), 'waiting_list_position': self.session.get('waiting_list_position'), 'players': self.session.get('registration_cart_players', []), - 'expiry': self.get_cart_expiry(), + 'expiry': expiry_datetime, # Now a datetime object, not a string + 'is_cart_expired': self.is_cart_expired(), 'mobile_number': self.session.get('registration_mobile_number', user_phone) } diff --git a/tournaments/templates/register_tournament.html b/tournaments/templates/register_tournament.html index 2fd3551..ac2fa26 100644 --- a/tournaments/templates/register_tournament.html +++ b/tournaments/templates/register_tournament.html @@ -15,7 +15,7 @@
-

Inscription : {{ tournament.display_name }} {{ tournament.get_federal_age_category_display}}

+

Inscription : {{ tournament.display_name }} {{ tournament.get_federal_age_category_display}}

@@ -28,8 +28,15 @@ {% else %} {% if not registration_successful %}
-

Votre session d'inscription est active. Complétez le formulaire pour confirmer votre participation.

-

DEBUG reserved_spots: {{ tournament.reserved_spots }}

+

Votre session d'inscription est active. Complétez le formulaire dans le délai accordé pour confirmer votre participation et garantir votre place.

+ {% if not cart_data.is_cart_expired %} +

Votre session d'inscription expirera le {{ cart_data.expiry|date:"d/m/Y à H:i" }}

+

Temps restant: {{ cart_data.expiry|timeuntil }}

+ {% else %} +

+ Votre session d'inscription a expiré. Veuillez recommencer le processus d'inscription. Votre place n'est plus garantie. +

+ {% endif %}
{% endif %} @@ -196,4 +203,88 @@
+ + {% endblock %} diff --git a/tournaments/views.py b/tournaments/views.py index f8a9e20..176f621 100644 --- a/tournaments/views.py +++ b/tournaments/views.py @@ -1186,6 +1186,11 @@ def tournament_payment_success(request, tournament_id): success = payment_service.process_successful_payment(str(tournament_id), checkout_session) if success: + # Set a flag for successful registration if the payment was from registration page + source_page = request.session.get('payment_source_page', 'tournament_info') + if source_page == 'register_tournament': + request.session['registration_successful'] = True + messages.success(request, "Paiement réussi et inscription confirmée !") else: messages.error(request, "Erreur lors du traitement du paiement.") @@ -1206,16 +1211,35 @@ def tournament_payment_success(request, tournament_id): # Redirect to the appropriate page if source_page == 'register_tournament': - # For payments during registration, redirect back to tournament info - # since the registration is now complete - return redirect('tournament-info', tournament_id=tournament_id) + # For payments during registration, redirect back to registration page + # with registration_successful flag in session + return redirect('register_tournament', tournament_id=tournament_id) else: - # For direct payments, also go to tournament info + # For direct payments, go to tournament info return redirect('tournament-info', tournament_id=tournament_id) @csrf_protect def register_tournament(request, tournament_id): tournament = get_object_or_404(Tournament, id=tournament_id) + + # Check for registration_successful flag + registration_successful = request.session.pop('registration_successful', False) + + # If registration was successful, render success page immediately + if registration_successful: + storage = messages.get_messages(request) + for message in storage: + # Iterate through messages to clear them + pass # This actually consumes the messages + storage.used = True # Mark all messages as used + context = { + 'tournament': tournament, + 'registration_successful': True, + 'current_players': [], + 'cart_data': {'players': []} + } + return render(request, 'register_tournament.html', context) + cart_manager = RegistrationCartManager(request) # Debug session content @@ -1239,6 +1263,12 @@ def register_tournament(request, tournament_id): # We're returning from Stripe, don't reinitialize the cart pass else: + storage = messages.get_messages(request) + for message in storage: + # Iterate through messages to clear them + pass # This actually consumes the messages + storage.used = True # Mark all messages as used + # ALWAYS initialize a fresh cart when entering the registration page (GET request) # This ensures no old cart data persists cart_manager.initialize_cart(tournament_id)