Refactor contact information handling in tournament registration

mailing
Razmig Sarkissian 1 month ago
parent 0074548dd4
commit 371bce35d7
  1. 2
      tournaments/forms.py
  2. 3
      tournaments/models/player_registration.py
  3. 10
      tournaments/models/team_registration.py
  4. 14
      tournaments/services/email_service.py
  5. 2
      tournaments/services/payment_service.py
  6. 23
      tournaments/services/tournament_registration.py
  7. 8
      tournaments/templates/register_tournament.html
  8. 81
      tournaments/views.py

@ -171,7 +171,7 @@ class SimpleForm(forms.Form):
class TournamentRegistrationForm(forms.Form): class TournamentRegistrationForm(forms.Form):
#first_name = forms.CharField(label='Prénom', max_length=50) #first_name = forms.CharField(label='Prénom', max_length=50)
#last_name = forms.CharField(label='Nom', max_length=50) #last_name = forms.CharField(label='Nom', max_length=50)
email = forms.EmailField(label='E-mail', widget=forms.EmailInput(attrs={'readonly': 'readonly'})) email = forms.EmailField(label='E-mail')
mobile_number = forms.CharField( mobile_number = forms.CharField(
label='Téléphone', label='Téléphone',
max_length=15, max_length=15,

@ -228,3 +228,6 @@ class PlayerRegistration(TournamentSubModel):
return self.team_registration.tournament.entry_fee return self.team_registration.tournament.entry_fee
else: else:
return 0 return 0
def player_contact(self):
return self.contact_email or self.email

@ -550,3 +550,13 @@ class TeamRegistration(TournamentSubModel):
# Check payment status for each player # Check payment status for each player
payment_statuses = [player.get_player_registration_fee() for player in player_registrations] payment_statuses = [player.get_player_registration_fee() for player in player_registrations]
return sum(payment_statuses) return sum(payment_statuses)
def team_contact(self):
if self.user:
return self.user.email
else:
player_registrations = self.players_sorted_by_captain
if len(player_registrations) > 0:
return player_registrations[0].player_contact()
return None

@ -531,7 +531,7 @@ class TournamentEmailService:
topic = message_type.email_topic(tournament.federal_level_category, captain.time_to_confirm) topic = message_type.email_topic(tournament.federal_level_category, captain.time_to_confirm)
email_subject = TournamentEmailService.email_subject(tournament, topic) email_subject = TournamentEmailService.email_subject(tournament, topic)
TournamentEmailService._send_email(captain.email, email_subject, email_body) TournamentEmailService._send_email(captain.player_contact(), email_subject, email_body)
@staticmethod @staticmethod
def _build_email_content(message_type, recipient, tournament, tournament_details_str, other_player, request=None, waiting_list_position=None): def _build_email_content(message_type, recipient, tournament, tournament_details_str, other_player, request=None, waiting_list_position=None):
@ -721,11 +721,13 @@ class TournamentEmailService:
tournament_prefix_that = federal_level_category.localized_prefix_that() tournament_prefix_that = federal_level_category.localized_prefix_that()
processed_emails = set() processed_emails = set()
for player in player_registrations: for player in player_registrations:
if not player.email or not player.registered_online: # Check both email and contact_email fields
player_email = player.player_contact()
if not player_email or not player.registered_online:
continue continue
if player.email in processed_emails: if player_email in processed_emails:
continue continue
processed_emails.add(player.email) processed_emails.add(player_email)
tournament_details_str = tournament.build_tournament_details_str() tournament_details_str = tournament.build_tournament_details_str()
other_player = team_registration.get_other_player(player) if len(player_registrations) > 1 else None other_player = team_registration.get_other_player(player) if len(player_registrations) > 1 else None
@ -772,7 +774,7 @@ class TournamentEmailService:
email_body = "".join(body_parts) email_body = "".join(body_parts)
email_subject = TournamentEmailService.email_subject(tournament, "Confirmation de paiement") email_subject = TournamentEmailService.email_subject(tournament, "Confirmation de paiement")
TournamentEmailService._send_email(player.email, email_subject, email_body) TournamentEmailService._send_email(player.player_contact(), email_subject, email_body)
@staticmethod @staticmethod
def send_refund_confirmation(tournament, team_registration, refund_details): def send_refund_confirmation(tournament, team_registration, refund_details):
@ -856,4 +858,4 @@ class TournamentEmailService:
email_body = "".join(body_parts) email_body = "".join(body_parts)
email_subject = TournamentEmailService.email_subject(tournament, "Confirmation de remboursement") email_subject = TournamentEmailService.email_subject(tournament, "Confirmation de remboursement")
TournamentEmailService._send_email(player.email, email_subject, email_body) TournamentEmailService._send_email(player.player_contact(), email_subject, email_body)

@ -76,6 +76,8 @@ class PaymentService:
if not team_registration: if not team_registration:
print(f"[TOURNAMENT PAYMENT] Failed to create team registration") print(f"[TOURNAMENT PAYMENT] Failed to create team registration")
raise Exception("Erreur lors de la création de la réservation") raise Exception("Erreur lors de la création de la réservation")
if not customer_email:
customer_email = team_registration.team_contact()
team_registration_id = team_registration.id team_registration_id = team_registration.id
print(f"[TOURNAMENT PAYMENT] Created team registration: {team_registration_id}") print(f"[TOURNAMENT PAYMENT] Created team registration: {team_registration_id}")

@ -38,7 +38,8 @@ class RegistrationCartManager:
'registration_tournament_id', 'registration_tournament_id',
'registration_cart_players', 'registration_cart_players',
'registration_cart_expiry', 'registration_cart_expiry',
'registration_mobile_number' 'registration_mobile_number',
'registration_email'
] ]
for key in keys_to_delete: for key in keys_to_delete:
if key in self.session: if key in self.session:
@ -132,9 +133,12 @@ class RegistrationCartManager:
# Get user phone if authenticated # Get user phone if authenticated
user_phone = '' user_phone = ''
user_email = ''
if hasattr(self.request.user, 'phone'): if hasattr(self.request.user, 'phone'):
user_phone = self.request.user.phone user_phone = self.request.user.phone
if hasattr(self.request.user, 'email'):
user_email = self.request.user.email
# Parse the expiry time from ISO format to datetime # Parse the expiry time from ISO format to datetime
expiry_str = self.get_cart_expiry() expiry_str = self.get_cart_expiry()
expiry_datetime = None expiry_datetime = None
@ -155,7 +159,8 @@ class RegistrationCartManager:
'is_cart_expired': self.is_cart_expired(), 'is_cart_expired': self.is_cart_expired(),
'team_fee_from_cart_players': self.team_fee_from_cart_players(), 'team_fee_from_cart_players': self.team_fee_from_cart_players(),
'team_fee_from_cart_players_formatted': self.team_fee_from_cart_players_formatted(), 'team_fee_from_cart_players_formatted': self.team_fee_from_cart_players_formatted(),
'mobile_number': self.session.get('registration_mobile_number', user_phone) 'mobile_number': self.session.get('registration_mobile_number', user_phone),
'email': self.session.get('registration_email', user_email),
} }
# Debug: print the cart content # Debug: print the cart content
@ -370,11 +375,13 @@ class RegistrationCartManager:
return True, "Joueur retiré." return True, "Joueur retiré."
def update_contact_info(self, mobile_number=None): def update_contact_info(self, email=None, mobile_number=None):
"""Update contact info for the cart""" """Update contact info for the cart"""
if self.is_cart_expired(): if self.is_cart_expired():
return False, "Votre session d'inscription a expiré, veuillez réessayer." return False, "Votre session d'inscription a expiré, veuillez réessayer."
if email is not None:
self.session['registration_email'] = email
if mobile_number is not None: if mobile_number is not None:
self.session['registration_mobile_number'] = mobile_number self.session['registration_mobile_number'] = mobile_number
@ -394,6 +401,7 @@ class RegistrationCartManager:
tournament_id = cart_data.get('tournament_id') tournament_id = cart_data.get('tournament_id')
players = cart_data.get('players') players = cart_data.get('players')
mobile_number = cart_data.get('mobile_number') mobile_number = cart_data.get('mobile_number')
email = cart_data.get('email')
# Validate cart data # Validate cart data
if not tournament_id: if not tournament_id:
@ -435,7 +443,7 @@ class RegistrationCartManager:
registration_date=timezone.now(), registration_date=timezone.now(),
walk_out=False, walk_out=False,
weight=weight, weight=weight,
user=self.request.user user= self.request.user if self.request.user.is_authenticated else None
) )
for player_data in players: # Compute rank and sex using the original logic for player_data in players: # Compute rank and sex using the original logic
@ -511,8 +519,8 @@ class RegistrationCartManager:
rank=player_data.get('rank'), rank=player_data.get('rank'),
computed_rank=player_data.get('computed_rank'), computed_rank=player_data.get('computed_rank'),
licence_id=player_data.get('licence_id'), licence_id=player_data.get('licence_id'),
email=matching_user.email if matching_user else player_data.get('email'), contact_email=matching_user.email if matching_user else player_data.get('email', email),
phone_number=matching_user.phone if matching_user else player_data.get('mobile_number'), contact_phone_number=matching_user.phone if matching_user else player_data.get('mobile_number', mobile_number),
registration_status=RegistrationStatus.CONFIRMED if self.session.get('waiting_list_position', 0) < 0 else RegistrationStatus.WAITING registration_status=RegistrationStatus.CONFIRMED if self.session.get('waiting_list_position', 0) < 0 else RegistrationStatus.WAITING
) )
@ -533,7 +541,8 @@ class RegistrationCartManager:
'registration_tournament_id', 'registration_tournament_id',
'registration_cart_players', 'registration_cart_players',
'registration_cart_expiry', 'registration_cart_expiry',
'registration_mobile_number' 'registration_mobile_number',
'registration_email',
] ]
for key in keys_to_clear: for key in keys_to_clear:

@ -32,7 +32,13 @@
<p><strong>✅ Votre paiement a bien été effectué et enregistré.</strong></p> <p><strong>✅ Votre paiement a bien été effectué et enregistré.</strong></p>
{% endif %} {% endif %}
<p style="text-align: justify;"> <p style="text-align: justify;">
Un email de confirmation a été envoyé à l'adresse associée à votre compte Padel Club ({{ user.email }}). Pensez à vérifier vos spams si vous ne recevez pas l'email. En cas de problème, contactez le juge-arbitre. {% if user.email %}
Un email de confirmation a été envoyé à l'adresse associée à votre compte Padel Club ({{ user.email }}). Pensez à vérifier vos spams si vous ne recevez pas l'email. En cas de problème, contactez le juge-arbitre.
{% elif registered_team.team_contact %}
Un email de confirmation a été envoyé à l'adresse associée à votre compte Padel Club ({{ registered_team.team_contact }}). Pensez à vérifier vos spams si vous ne recevez pas l'email. En cas de problème, contactez le juge-arbitre.
{% else %}
Aucun email de confirmation n'a été envoyé car vous n'avez pas fourni d'adresse email. Contactez le juge-arbitre.
{% endif %}
</p> </p>
{% else %} {% else %}
{% if not registration_successful %} {% if not registration_successful %}

@ -1583,9 +1583,14 @@ def proceed_to_payment(request, tournament_id):
messages.error(request, f"Erreur lors de la création de la session de paiement: {str(e)}") messages.error(request, f"Erreur lors de la création de la session de paiement: {str(e)}")
return redirect('tournament-info', tournament_id=tournament_id) return redirect('tournament-info', tournament_id=tournament_id)
@login_required
def tournament_payment_success(request, tournament_id): def tournament_payment_success(request, tournament_id):
"""Handle successful Stripe payment for tournament registration""" """Handle successful Stripe payment for tournament registration"""
# For unauthenticated users, process payment and redirect directly to registration page
if not request.user.is_authenticated:
return _handle_unauthenticated_payment_success(request, tournament_id)
# Original logic for authenticated users
# Get checkout session ID from session # Get checkout session ID from session
checkout_session_id = request.session.get('stripe_checkout_session_id') checkout_session_id = request.session.get('stripe_checkout_session_id')
if not checkout_session_id: if not checkout_session_id:
@ -1641,6 +1646,68 @@ def tournament_payment_success(request, tournament_id):
# For direct payments, go to tournament info # For direct payments, go to tournament info
return redirect('tournament-info', tournament_id=tournament_id) return redirect('tournament-info', tournament_id=tournament_id)
def _handle_unauthenticated_payment_success(request, tournament_id):
"""Handle payment success for unauthenticated users"""
print(f"[PAYMENT SUCCESS] Handling unauthenticated user payment for tournament {tournament_id}")
# Get checkout session ID from session
checkout_session_id = request.session.get('stripe_checkout_session_id')
if not checkout_session_id:
print(f"[PAYMENT SUCCESS] No checkout session ID found")
messages.error(request, "Session de paiement introuvable.")
return redirect('register_tournament', tournament_id=tournament_id)
try:
# Verify payment status with Stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
print(f"[PAYMENT SUCCESS] Retrieving checkout session: {checkout_session_id}")
stripe_account_id = request.session.get('stripe_account_id')
if not stripe_account_id:
checkout_session = stripe.checkout.Session.retrieve(checkout_session_id)
else:
checkout_session = stripe.checkout.Session.retrieve(checkout_session_id, stripe_account=stripe_account_id)
print(f"[PAYMENT SUCCESS] Payment status: {checkout_session.payment_status}")
if checkout_session.payment_status == 'paid':
# Process the payment success
payment_service = PaymentService(request)
success = payment_service.process_successful_payment(checkout_session)
print(f"[PAYMENT SUCCESS] Payment processing success: {success}")
if success:
# Always set success flags for unauthenticated users since they come from registration
request.session['registration_successful'] = True
request.session['registration_paid'] = True
# Clear payment-related session data
for key in ['stripe_checkout_session_id', 'team_registration_id', 'payment_source_page', 'stripe_account_id']:
if key in request.session:
del request.session[key]
print(f"[PAYMENT SUCCESS] Redirecting to registration page with success flags")
# Redirect directly to registration page with success context
return redirect('register_tournament', tournament_id=tournament_id)
else:
messages.error(request, "Erreur lors du traitement du paiement.")
else:
messages.error(request, "Le paiement n'a pas été complété.")
except Exception as e:
print(f"[PAYMENT SUCCESS] Payment processing error: {str(e)}")
messages.error(request, f"Erreur lors de la vérification du paiement: {str(e)}")
# Clean up session variables even if there was an error
for key in ['stripe_checkout_session_id', 'team_registration_id', 'payment_source_page', 'stripe_account_id']:
if key in request.session:
del request.session[key]
# Always redirect to registration page for unauthenticated users
return redirect('register_tournament', tournament_id=tournament_id)
@csrf_protect @csrf_protect
def register_tournament(request, tournament_id): def register_tournament(request, tournament_id):
tournament = get_object_or_404(Tournament, id=tournament_id) tournament = get_object_or_404(Tournament, id=tournament_id)
@ -1657,7 +1724,7 @@ def register_tournament(request, tournament_id):
# Check for registration_successful flag # Check for registration_successful flag
registration_successful = request.session.pop('registration_successful', False) registration_successful = request.session.pop('registration_successful', False)
registration_paid = request.session.pop('registration_paid', False) registration_paid = request.session.pop('registration_paid', False)
registered_team = None
# Handle payment cancellation - check for cancelled team registration # Handle payment cancellation - check for cancelled team registration
cancel_team_registration_id = request.session.pop('cancel_team_registration_id', None) cancel_team_registration_id = request.session.pop('cancel_team_registration_id', None)
if cancel_team_registration_id: if cancel_team_registration_id:
@ -1676,7 +1743,8 @@ def register_tournament(request, tournament_id):
if not team_registration.is_paid(): if not team_registration.is_paid():
team_registration.delete() team_registration.delete()
print(f"[PAYMENT CANCEL] Deleted unpaid team registration {cancel_team_registration_id}") print(f"[PAYMENT CANCEL] Deleted unpaid team registration {cancel_team_registration_id}")
else:
registered_team = team_registration
except TeamRegistration.DoesNotExist: except TeamRegistration.DoesNotExist:
print(f"[PAYMENT CANCEL] Team registration {cancel_team_registration_id} not found") print(f"[PAYMENT CANCEL] Team registration {cancel_team_registration_id} not found")
except Exception as e: except Exception as e:
@ -1702,6 +1770,7 @@ def register_tournament(request, tournament_id):
'tournament': tournament, 'tournament': tournament,
'registration_successful': True, 'registration_successful': True,
'registration_paid': registration_paid, 'registration_paid': registration_paid,
'registered_team': registered_team,
'current_players': [], 'current_players': [],
'cart_data': {'players': []} 'cart_data': {'players': []}
} }
@ -1823,6 +1892,7 @@ def handle_add_player_request(request, tournament, cart_manager, context):
if team_form.is_valid(): if team_form.is_valid():
# Update cart with mobile number before adding player # Update cart with mobile number before adding player
cart_manager.update_contact_info( cart_manager.update_contact_info(
email=team_form.cleaned_data.get('email'),
mobile_number=team_form.cleaned_data.get('mobile_number') mobile_number=team_form.cleaned_data.get('mobile_number')
) )
@ -1834,7 +1904,7 @@ def handle_add_player_request(request, tournament, cart_manager, context):
context['current_players'] = cart_data['players'] context['current_players'] = cart_data['players']
context['cart_data'] = cart_data context['cart_data'] = cart_data
context['team_form'] = TournamentRegistrationForm(initial={ context['team_form'] = TournamentRegistrationForm(initial={
'email': request.user.email if request.user.is_authenticated else '', 'email': request.user.email if request.user.is_authenticated else cart_data.get('email', ''),
'mobile_number': cart_data.get('mobile_number', '') 'mobile_number': cart_data.get('mobile_number', '')
}) })
@ -1898,6 +1968,7 @@ def handle_register_team_request(request, tournament, cart_manager, context):
# Update cart with contact info # Update cart with contact info
cart_manager.update_contact_info( cart_manager.update_contact_info(
email=team_form.cleaned_data.get('email'),
mobile_number=team_form.cleaned_data.get('mobile_number') mobile_number=team_form.cleaned_data.get('mobile_number')
) )
@ -1922,6 +1993,7 @@ def handle_register_team_request(request, tournament, cart_manager, context):
) )
context['registration_successful'] = True context['registration_successful'] = True
context['registered_team'] = result
context['registration_paid'] = False context['registration_paid'] = False
context['current_players'] = [] context['current_players'] = []
context['add_player_form'] = None # No more adding players after success context['add_player_form'] = None # No more adding players after success
@ -1939,6 +2011,7 @@ def handle_payment_request(request, cart_manager, context, tournament_id):
if team_form.is_valid(): if team_form.is_valid():
# Update cart with contact info # Update cart with contact info
cart_manager.update_contact_info( cart_manager.update_contact_info(
email=team_form.cleaned_data.get('email'),
mobile_number=team_form.cleaned_data.get('mobile_number') mobile_number=team_form.cleaned_data.get('mobile_number')
) )

Loading…
Cancel
Save