parent
42090b5ab7
commit
28e39be609
@ -0,0 +1,23 @@ |
||||
# Generated by Django 5.1 on 2025-04-09 18:43 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('tournaments', '0118_remove_playerregistration_payment_status_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='tournament', |
||||
name='enable_online_payment', |
||||
field=models.BooleanField(default=False), |
||||
), |
||||
migrations.AddField( |
||||
model_name='tournament', |
||||
name='online_payment_is_mandatory', |
||||
field=models.BooleanField(default=False), |
||||
), |
||||
] |
||||
@ -0,0 +1,23 @@ |
||||
# Generated by Django 5.1 on 2025-04-09 19:06 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('tournaments', '0119_tournament_enable_online_payment_and_more'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AddField( |
||||
model_name='tournament', |
||||
name='enable_online_payment_refund', |
||||
field=models.BooleanField(default=False), |
||||
), |
||||
migrations.AddField( |
||||
model_name='tournament', |
||||
name='refund_date_limit', |
||||
field=models.DateTimeField(blank=True, null=True), |
||||
), |
||||
] |
||||
@ -0,0 +1,193 @@ |
||||
from django.shortcuts import get_object_or_404, redirect |
||||
from django.conf import settings |
||||
from django.urls import reverse |
||||
from django.contrib import messages |
||||
import stripe |
||||
|
||||
from ..models import TeamRegistration, PlayerRegistration, Tournament |
||||
from ..models.player_registration import PlayerPaymentType, RegistrationStatus |
||||
from .email_service import TournamentEmailService |
||||
from .tournament_registration import RegistrationCartManager |
||||
from ..utils.extensions import is_not_sqlite_backend |
||||
|
||||
class PaymentService: |
||||
""" |
||||
Service for handling payment processing for tournament registrations |
||||
""" |
||||
|
||||
def __init__(self, request): |
||||
self.request = request |
||||
self.stripe_api_key = settings.STRIPE_SECRET_KEY |
||||
|
||||
def create_checkout_session(self, tournament_id, team_fee, cart_data=None, team_registration_id=None): |
||||
""" |
||||
Create a Stripe checkout session for tournament payment |
||||
""" |
||||
stripe.api_key = self.stripe_api_key |
||||
tournament = get_object_or_404(Tournament, id=tournament_id) |
||||
|
||||
# Get user email if authenticated |
||||
customer_email = self.request.user.email if self.request.user.is_authenticated else None |
||||
|
||||
# Determine the appropriate cancel URL based on the context |
||||
if team_registration_id: |
||||
# If we're paying for an existing registration, go back to tournament info |
||||
cancel_url = self.request.build_absolute_uri( |
||||
reverse('tournament-info', kwargs={'tournament_id': tournament_id}) |
||||
) |
||||
else: |
||||
# If we're in the registration process, go back to registration form |
||||
cancel_url = self.request.build_absolute_uri( |
||||
reverse('register_tournament', kwargs={'tournament_id': tournament_id}) |
||||
) |
||||
|
||||
# Common checkout session parameters |
||||
checkout_session_params = { |
||||
'payment_method_types': ['card'], |
||||
'line_items': [{ |
||||
'price_data': { |
||||
'currency': 'eur', |
||||
'product_data': { |
||||
'name': f'{tournament.broadcast_display_name()} du {tournament.formatted_start_date()}', |
||||
'description': f'Lieu {tournament.event.club.name}', |
||||
}, |
||||
'unit_amount': int(team_fee * 100), # Amount in cents |
||||
}, |
||||
'quantity': 1, |
||||
}], |
||||
'mode': 'payment', |
||||
'success_url': self.request.build_absolute_uri( |
||||
reverse('tournament-payment-success', kwargs={'tournament_id': tournament_id}) |
||||
), |
||||
'cancel_url': cancel_url, |
||||
'metadata': { |
||||
'tournament_id': str(tournament_id), # Convert UUID to string |
||||
'user_id': str(self.request.user.id) if self.request.user.is_authenticated else None, # Convert UUID to string |
||||
'source_page': 'tournament_info' if team_registration_id else 'register_tournament', |
||||
} |
||||
} |
||||
|
||||
# Add cart or team data to metadata based on payment context |
||||
if cart_data: |
||||
checkout_session_params['metadata']['registration_cart_id'] = str(cart_data['cart_id']) # Convert to string |
||||
elif team_registration_id: |
||||
checkout_session_params['metadata']['team_registration_id'] = str(team_registration_id) # Convert to string |
||||
self.request.session['team_registration_id'] = str(team_registration_id) # Convert to string |
||||
|
||||
# Add customer_email if available |
||||
if customer_email: |
||||
checkout_session_params['customer_email'] = customer_email |
||||
|
||||
# Create the checkout session |
||||
checkout_session = stripe.checkout.Session.create(**checkout_session_params) |
||||
|
||||
# Store checkout session ID and source page in session |
||||
self.request.session['stripe_checkout_session_id'] = checkout_session.id |
||||
self.request.session['payment_source_page'] = 'tournament_info' if team_registration_id else 'register_tournament' |
||||
self.request.session.modified = True |
||||
|
||||
return checkout_session |
||||
|
||||
def process_successful_payment(self, tournament_id, checkout_session): |
||||
""" |
||||
Process a successful Stripe payment |
||||
Returns a tuple (success, redirect_response) |
||||
""" |
||||
print(f"Processing payment for tournament {tournament_id}") |
||||
tournament = get_object_or_404(Tournament, id=tournament_id) |
||||
|
||||
# Check if this is a payment for an existing team registration |
||||
team_registration_id = self.request.session.get('team_registration_id') |
||||
print(f"Team registration ID from session: {team_registration_id}") |
||||
|
||||
# Track payment statuses for debugging |
||||
payment_statuses = [] |
||||
|
||||
if team_registration_id: |
||||
success = self._process_direct_payment(checkout_session) |
||||
payment_statuses.append(success) |
||||
print(f"Direct payment processing result: {success}") |
||||
else: |
||||
# This is a payment during registration process |
||||
success = self._process_registration_payment(tournament, checkout_session) |
||||
payment_statuses.append(success) |
||||
print(f"Registration payment processing result: {success}") |
||||
|
||||
# Print combined payment status |
||||
print(f"Payment statuses: {payment_statuses}") |
||||
print(any(payment_statuses)) |
||||
|
||||
# Clear checkout session ID |
||||
if 'stripe_checkout_session_id' in self.request.session: |
||||
del self.request.session['stripe_checkout_session_id'] |
||||
|
||||
return any(payment_statuses) |
||||
|
||||
def _process_direct_payment(self, checkout_session): |
||||
"""Process payment for an existing team registration""" |
||||
team_registration_id = self.request.session.get('team_registration_id') |
||||
if not team_registration_id: |
||||
print("No team registration ID found in session") |
||||
return False |
||||
|
||||
try: |
||||
print(f"Looking for team registration with ID: {team_registration_id}") |
||||
team_registration = TeamRegistration.objects.get(id=team_registration_id) |
||||
success = self._update_registration_payment_info( |
||||
team_registration, |
||||
checkout_session.payment_intent |
||||
) |
||||
|
||||
# Clean up session |
||||
if 'team_registration_id' in self.request.session: |
||||
del self.request.session['team_registration_id'] |
||||
|
||||
return success |
||||
except TeamRegistration.DoesNotExist: |
||||
print(f"Team registration not found with ID: {team_registration_id}") |
||||
return False |
||||
except Exception as e: |
||||
print(f"Error in _process_direct_payment: {str(e)}") |
||||
return False |
||||
|
||||
def _process_registration_payment(self, tournament, checkout_session): |
||||
"""Process payment made during registration""" |
||||
cart_manager = RegistrationCartManager(self.request) |
||||
cart_data = cart_manager.get_cart_data() |
||||
|
||||
# Checkout and create registration |
||||
success, result = cart_manager.checkout() |
||||
if not success: |
||||
return False |
||||
|
||||
# Process payment for the new registration |
||||
team_registration = result # result is team_registration object |
||||
self._update_registration_payment_info( |
||||
team_registration, |
||||
checkout_session.payment_intent |
||||
) |
||||
|
||||
# Send confirmation email if appropriate |
||||
waiting_list_position = cart_data.get('waiting_list_position', -1) |
||||
if is_not_sqlite_backend(): |
||||
email_service = TournamentEmailService() |
||||
email_service.send_registration_confirmation( |
||||
self.request, |
||||
tournament, |
||||
team_registration, |
||||
waiting_list_position |
||||
) |
||||
|
||||
return True |
||||
|
||||
def _update_registration_payment_info(self, team_registration, payment_intent_id): |
||||
"""Update player registrations with payment information""" |
||||
player_registrations = PlayerRegistration.objects.filter(team_registration=team_registration) |
||||
|
||||
for player_reg in player_registrations: |
||||
player_reg.payment_type = PlayerPaymentType.CREDIT_CARD |
||||
player_reg.registration_status = RegistrationStatus.CONFIRMED |
||||
player_reg.payment_id = payment_intent_id |
||||
player_reg.save() |
||||
|
||||
return True |
||||
@ -1,365 +0,0 @@ |
||||
from django.utils import timezone |
||||
import uuid |
||||
import datetime |
||||
from ..models import PlayerRegistration, TeamRegistration, Tournament |
||||
from ..utils.licence_validator import LicenseValidator |
||||
from ..utils.player_search import get_player_name_from_csv |
||||
|
||||
def get_or_create_registration_cart_id(request): |
||||
"""Get or create a registration cart ID in the session""" |
||||
if 'registration_cart_id' not in request.session: |
||||
request.session['registration_cart_id'] = str(uuid.uuid4()) |
||||
return request.session['registration_cart_id'] |
||||
|
||||
def get_cart_expiry(request): |
||||
"""Get the cart expiry time from the session""" |
||||
if 'registration_cart_expiry' not in request.session: |
||||
# Set default expiry to 30 minutes from now |
||||
expiry = timezone.now() + datetime.timedelta(minutes=30) |
||||
request.session['registration_cart_expiry'] = expiry.isoformat() |
||||
return request.session['registration_cart_expiry'] |
||||
|
||||
def is_cart_expired(request): |
||||
"""Check if the registration cart is expired""" |
||||
if 'registration_cart_expiry' not in request.session: |
||||
return False |
||||
|
||||
expiry_str = request.session['registration_cart_expiry'] |
||||
try: |
||||
expiry = datetime.datetime.fromisoformat(expiry_str) |
||||
return timezone.now() > expiry |
||||
except (ValueError, TypeError): |
||||
return True |
||||
|
||||
def reset_cart_expiry(request): |
||||
"""Reset the cart expiry time""" |
||||
expiry = timezone.now() + datetime.timedelta(minutes=30) |
||||
request.session['registration_cart_expiry'] = expiry.isoformat() |
||||
request.session.modified = True |
||||
|
||||
def get_tournament_from_cart(request): |
||||
"""Get the tournament ID associated with the current cart""" |
||||
return request.session.get('registration_tournament_id') |
||||
|
||||
def initialize_registration_cart(request, tournament_id): |
||||
"""Initialize a new registration cart for a tournament""" |
||||
# Clear any existing cart |
||||
clear_registration_cart(request) |
||||
|
||||
try: |
||||
tournament = Tournament.objects.get(id=tournament_id) |
||||
except Tournament.DoesNotExist: |
||||
return False, "Tournoi introuvable." |
||||
|
||||
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.save() |
||||
|
||||
# Set up the new cart |
||||
request.session['registration_cart_id'] = str(uuid.uuid4()) |
||||
request.session['waiting_list_position'] = waiting_list_position |
||||
request.session['registration_tournament_id'] = tournament_id |
||||
request.session['registration_cart_players'] = [] |
||||
reset_cart_expiry(request) |
||||
request.session.modified = True |
||||
|
||||
def get_registration_cart_data(request): |
||||
"""Get the data for the current registration cart""" |
||||
# Ensure cart players array exists |
||||
if 'registration_cart_players' not in request.session: |
||||
request.session['registration_cart_players'] = [] |
||||
request.session.modified = True |
||||
|
||||
# Ensure tournament ID exists |
||||
if 'registration_tournament_id' not in request.session: |
||||
# If no tournament ID but we have players, this is an inconsistency |
||||
if request.session.get('registration_cart_players'): |
||||
print("WARNING: Found players but no tournament ID - clearing players") |
||||
request.session['registration_cart_players'] = [] |
||||
request.session.modified = True |
||||
|
||||
cart_data = { |
||||
'cart_id': get_or_create_registration_cart_id(request), |
||||
'tournament_id': request.session.get('registration_tournament_id'), |
||||
'waiting_list_position': request.session.get('waiting_list_position'), |
||||
'players': request.session.get('registration_cart_players', []), |
||||
'expiry': get_cart_expiry(request), |
||||
'mobile_number': request.session.get('registration_mobile_number', |
||||
request.user.phone if hasattr(request.user, 'phone') else '') |
||||
} |
||||
|
||||
# Debug: print the cart content |
||||
print(f"Cart data - Tournament ID: {cart_data['tournament_id']}") |
||||
print(f"Cart data - Players count: {len(cart_data['players'])}") |
||||
|
||||
return cart_data |
||||
|
||||
def add_player_to_cart(request, player_data): |
||||
"""Add a player to the registration cart""" |
||||
if is_cart_expired(request): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
# Get cart data |
||||
tournament_id = request.session.get('registration_tournament_id') |
||||
if not tournament_id: |
||||
return False, "Pas d'inscription active." |
||||
|
||||
# Get tournament |
||||
try: |
||||
tournament = Tournament.objects.get(id=tournament_id) |
||||
except Tournament.DoesNotExist: |
||||
return False, "Tournoi introuvable." |
||||
|
||||
# Get existing players directly from session |
||||
players = request.session.get('registration_cart_players', []) |
||||
|
||||
# Debug: Initial players count |
||||
print(f"Before adding - Players in session: {len(players)}") |
||||
|
||||
# Check if we've reached the team limit (usually 2 for padel) |
||||
if len(players) >= 2: # Assuming teams of 2 for padel |
||||
return False, "Nombre maximum de joueurs déjà ajouté." |
||||
|
||||
# Process player data |
||||
licence_id = player_data.get('licence_id', '').upper() if player_data.get('licence_id') else None |
||||
first_name = player_data.get('first_name', '') |
||||
last_name = player_data.get('last_name', '').upper() |
||||
|
||||
# Handle case where user is authenticated, has no license, and license is required |
||||
if tournament.license_is_required: |
||||
# If license is required but not provided |
||||
if not licence_id: |
||||
# First player (authentication check) or partner |
||||
user_message = "Le numéro de licence est obligatoire." if len(players) == 0 else "Le numéro de licence de votre partenaire est obligatoire." |
||||
return False, user_message |
||||
|
||||
# Validate the license format |
||||
validator = LicenseValidator(licence_id) |
||||
if not validator.validate_license(): |
||||
return False, "Le numéro de licence est invalide, la lettre ne correspond pas." |
||||
|
||||
# Check if player is already registered in tournament |
||||
stripped_license = validator.stripped_license |
||||
if _is_player_already_registered(stripped_license, tournament): |
||||
return False, "Un joueur avec ce numéro de licence est déjà inscrit dans une équipe." |
||||
|
||||
# Check if this is the authenticated user trying to register as first player |
||||
if request.user.is_authenticated and len(players) == 0 and request.user.licence_id is None: |
||||
# Try to update the user's license ID in the database |
||||
try: |
||||
request.user.licence_id = validator.computed_licence_id |
||||
request.user.save() |
||||
request.user.refresh_from_db() |
||||
except: |
||||
return False, "Erreur lors de la mise à jour de votre licence: cette licence est déjà utilisée par un autre joueur." |
||||
|
||||
# Check for duplicate licenses in cart |
||||
existing_licenses = [p.get('licence_id') for p in players if p.get('licence_id')] |
||||
if licence_id and licence_id in existing_licenses: |
||||
return False, "Ce joueur est déjà dans l'équipe." |
||||
|
||||
# Process based on whether license ID was provided and tournament rules |
||||
if licence_id: |
||||
# Get federation data |
||||
fed_data, found = get_player_name_from_csv(tournament.federal_category, licence_id) |
||||
if found and fed_data: |
||||
# Use federation data (including check for eligibility) |
||||
player_register_check = tournament.player_register_check(licence_id) |
||||
if player_register_check: |
||||
return False, ", ".join(player_register_check) |
||||
|
||||
# Update player data from federation data |
||||
player_data.update({ |
||||
'first_name': fed_data['first_name'], |
||||
'last_name': fed_data['last_name'], |
||||
'rank': fed_data['rank'], |
||||
'is_woman': fed_data['is_woman'], |
||||
'points': fed_data.get('points'), |
||||
'assimilation': fed_data.get('assimilation'), |
||||
'tournament_count': fed_data.get('tournament_count'), |
||||
'ligue_name': fed_data.get('ligue_name'), |
||||
'club_name': fed_data.get('club_name'), |
||||
'birth_year': fed_data.get('birth_year'), |
||||
'found_in_french_federation': True, |
||||
}) |
||||
elif tournament.license_is_required: |
||||
# License required but not found in federation data |
||||
return False, "La licence fournit n'a pas été trouvée dans la base FFT. Contactez le juge arbitre si cette licence est valide." |
||||
elif not first_name or not last_name: |
||||
# License not required or not found, but name is needed |
||||
return False, "Le prénom et le nom sont obligatoires pour les joueurs sans licence." |
||||
elif not tournament.license_is_required: |
||||
# License not required, check if name is provided |
||||
if not first_name or not last_name: |
||||
return False, "Le prénom et le nom sont obligatoires pour les joueurs sans licence." |
||||
|
||||
# Set default rank for players without a license |
||||
if player_data.get('rank') is None: |
||||
default_data, _ = get_player_name_from_csv(tournament.federal_category, None) |
||||
if default_data: |
||||
player_data['rank'] = default_data.get('rank') |
||||
player_data['is_woman'] = default_data.get('is_woman', False) |
||||
else: |
||||
# License is required but not provided |
||||
return False, "Le numéro de licence est obligatoire." |
||||
|
||||
# Add player to cart |
||||
players.append(player_data) |
||||
request.session['registration_cart_players'] = players |
||||
reset_cart_expiry(request) |
||||
request.session.modified = True |
||||
|
||||
return True, "Joueur ajouté avec succès." |
||||
|
||||
def remove_player_from_cart(request): |
||||
"""Remove the last player from the cart""" |
||||
if is_cart_expired(request): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
players = request.session.get('registration_cart_players', []) |
||||
if not players: |
||||
return False, "Pas de joueur à supprimer." |
||||
|
||||
# Remove last player |
||||
players.pop() |
||||
request.session['registration_cart_players'] = players |
||||
reset_cart_expiry(request) |
||||
request.session.modified = True |
||||
|
||||
# If cart is now empty and user is authenticated with license, re-add them automatically |
||||
if not players: |
||||
add_authenticated_user_to_cart(request) |
||||
|
||||
return True, "Joueur retiré." |
||||
|
||||
def update_cart_contact_info(request, mobile_number=None): |
||||
"""Update contact info for the cart""" |
||||
if is_cart_expired(request): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
if mobile_number is not None: |
||||
request.session['registration_mobile_number'] = mobile_number |
||||
|
||||
reset_cart_expiry(request) |
||||
request.session.modified = True |
||||
|
||||
return True, "Informations de contact mises à jour." |
||||
|
||||
def checkout_registration_cart(request): |
||||
"""Convert cart to an actual tournament registration""" |
||||
if is_cart_expired(request): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
# Get cart data |
||||
cart_data = get_registration_cart_data(request) |
||||
tournament_id = cart_data.get('tournament_id') |
||||
players = cart_data.get('players') |
||||
mobile_number = cart_data.get('mobile_number') |
||||
|
||||
# Validate cart data |
||||
if not tournament_id: |
||||
return False, "Aucun tournoi sélectionné." |
||||
|
||||
if not players: |
||||
return False, "Aucun joueur dans l'inscription." |
||||
|
||||
# Get tournament |
||||
try: |
||||
tournament = Tournament.objects.get(id=tournament_id) |
||||
except Tournament.DoesNotExist: |
||||
return False, "Tournoi introuvable." |
||||
|
||||
# Check minimum players |
||||
if len(players) < tournament.minimum_player_per_team: |
||||
return False, f"Vous avez besoin d'au moins {tournament.minimum_player_per_team} joueurs pour vous inscrire." |
||||
|
||||
# Create team registration |
||||
team_registration = TeamRegistration.objects.create( |
||||
tournament=tournament, |
||||
registration_date=timezone.now(), |
||||
walk_out=False |
||||
) |
||||
|
||||
# Create player registrations |
||||
for idx, player_data in enumerate(players): |
||||
PlayerRegistration.objects.create( |
||||
team_registration=team_registration, |
||||
first_name=player_data.get('first_name', ''), |
||||
last_name=player_data.get('last_name', '').upper(), |
||||
licence_id=player_data.get('licence_id'), |
||||
rank=player_data.get('rank'), |
||||
points=player_data.get('points'), |
||||
club_name=player_data.get('club_name'), |
||||
ligue_name=player_data.get('ligue_name'), |
||||
email=player_data.get('email'), |
||||
phone_number=player_data.get('phone'), |
||||
assimilation=player_data.get('assimilation'), |
||||
tournament_played=player_data.get('tournament_count'), |
||||
birthdate=str(player_data.get('birth_year', '')), |
||||
captain=(idx == 0), # First player is captain |
||||
registered_online=True, |
||||
registration_status='CONFIRMED' if request.session['waiting_list_position'] < 0 else 'WAITING' |
||||
) |
||||
|
||||
# Update user phone if provided |
||||
if request.user.is_authenticated and mobile_number: |
||||
request.user.phone = mobile_number |
||||
request.user.save(update_fields=['phone']) |
||||
|
||||
# Clear the cart |
||||
clear_registration_cart(request) |
||||
tournament.reserved_spots = max(0, tournament.reserved_spots - 1) |
||||
tournament.save() |
||||
|
||||
return True, team_registration |
||||
|
||||
def clear_registration_cart(request): |
||||
"""Clear the registration cart""" |
||||
keys_to_clear = [ |
||||
'registration_cart_id', |
||||
'registration_tournament_id', |
||||
'registration_cart_players', |
||||
'registration_cart_expiry', |
||||
'registration_mobile_number' |
||||
] |
||||
|
||||
for key in keys_to_clear: |
||||
if key in request.session: |
||||
del request.session[key] |
||||
|
||||
request.session.modified = True |
||||
|
||||
def _is_player_already_registered(stripped_license, tournament): |
||||
"""Check if a player is already registered in the tournament""" |
||||
return PlayerRegistration.objects.filter( |
||||
team_registration__tournament=tournament, |
||||
licence_id__icontains=stripped_license, |
||||
team_registration__walk_out=False |
||||
).exists() |
||||
|
||||
def add_authenticated_user_to_cart(request): |
||||
""" |
||||
Adds the authenticated user to the cart if they have a valid license. |
||||
Returns True if added, False otherwise. |
||||
""" |
||||
if not request.user.is_authenticated or not request.user.licence_id: |
||||
return False |
||||
|
||||
# Create player data for the authenticated user |
||||
player_data = { |
||||
'first_name': request.user.first_name, |
||||
'last_name': request.user.last_name, |
||||
'licence_id': request.user.licence_id, |
||||
'email': request.user.email, |
||||
'phone': request.user.phone |
||||
} |
||||
|
||||
# Add the user to the cart |
||||
success, _ = add_player_to_cart(request, player_data) |
||||
return success |
||||
@ -1,372 +1,449 @@ |
||||
from django.utils import timezone |
||||
from ..forms import TournamentRegistrationForm, AddPlayerForm |
||||
from ..repositories import TournamentRegistrationRepository |
||||
from .email_service import TournamentEmailService |
||||
from django.contrib import messages |
||||
import uuid |
||||
import datetime |
||||
from ..models import PlayerRegistration, TeamRegistration, Tournament |
||||
from ..utils.licence_validator import LicenseValidator |
||||
from ..utils.player_search import get_player_name_from_csv |
||||
from tournaments.models import PlayerRegistration |
||||
from ..utils.extensions import is_not_sqlite_backend |
||||
from django.contrib.auth import get_user_model |
||||
from django.contrib.messages import get_messages |
||||
from django.db import IntegrityError |
||||
|
||||
class TournamentRegistrationService: |
||||
def __init__(self, request, tournament): |
||||
|
||||
class RegistrationCartManager: |
||||
""" |
||||
Manages the registration cart for tournament registrations. |
||||
Handles session-based cart operations, player additions/removals, |
||||
and checkout processes. |
||||
""" |
||||
|
||||
CART_EXPIRY_MINUTES = 30 |
||||
|
||||
def __init__(self, request): |
||||
self.request = request |
||||
self.tournament = tournament |
||||
self.context = {} |
||||
self.repository = TournamentRegistrationRepository() |
||||
self.email_service = TournamentEmailService() |
||||
|
||||
def initialize_context(self): |
||||
self.context = { |
||||
'tournament': self.tournament, |
||||
'registration_successful': False, |
||||
'team_form': None, |
||||
'add_player_form': None, |
||||
'current_players': self.request.session.get('team_registration', []), |
||||
} |
||||
return self.context |
||||
|
||||
def handle_post_request(self): |
||||
self.context['team_form'] = TournamentRegistrationForm(self.request.POST) |
||||
self.context['add_player_form'] = AddPlayerForm(self.request.POST) |
||||
|
||||
if 'add_player' in self.request.POST: |
||||
self.handle_add_player() |
||||
if 'remove_player' in self.request.POST: |
||||
self.handle_remove_player() |
||||
elif 'register_team' in self.request.POST: |
||||
self.handle_team_registration() |
||||
|
||||
def handle_remove_player(self): |
||||
team_registration = self.request.session.get('team_registration', []) |
||||
if team_registration: # Check if list is not empty |
||||
team_registration.pop() # Remove last element |
||||
self.request.session['team_registration'] = team_registration |
||||
self.context['current_players'] = team_registration |
||||
|
||||
def handle_add_player(self): |
||||
if not self.context['add_player_form'].is_valid(): |
||||
return |
||||
|
||||
# Clear existing messages if the form is valid |
||||
storage = get_messages(self.request) |
||||
# Iterate through the storage to clear it |
||||
for _ in storage: |
||||
pass |
||||
|
||||
player_data = self.context['add_player_form'].cleaned_data |
||||
licence_id = player_data.get('licence_id', '').upper() |
||||
|
||||
# Validate license |
||||
if not self._validate_license(licence_id): |
||||
return |
||||
|
||||
# Check for duplicate players |
||||
if self._is_duplicate_player(licence_id): |
||||
return |
||||
|
||||
# Check if player is already registered in tournament |
||||
if self._is_already_registered(licence_id): |
||||
return |
||||
|
||||
if self.request.user.is_authenticated and self.request.user.licence_id is None and len(self.context['current_players']) == 0: |
||||
if self._update_user_license(player_data.get('licence_id')) == False: |
||||
# if no licence id for authentificated user and trying to add him as first player of the team, we check his federal data |
||||
self._handle_invalid_names(licence_id, player_data) |
||||
self.session = request.session |
||||
|
||||
def get_or_create_cart_id(self): |
||||
"""Get or create a registration cart ID in the session""" |
||||
if 'registration_cart_id' not in self.session: |
||||
self.session['registration_cart_id'] = str(uuid.uuid4()) # Ensure it's a string |
||||
self.session.modified = True |
||||
return self.session['registration_cart_id'] |
||||
|
||||
def get_cart_expiry(self): |
||||
"""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) |
||||
self.session['registration_cart_expiry'] = expiry.isoformat() |
||||
self.session.modified = True |
||||
return self.session['registration_cart_expiry'] |
||||
|
||||
def is_cart_expired(self): |
||||
"""Check if the registration cart is expired""" |
||||
if 'registration_cart_expiry' not in self.session: |
||||
return False |
||||
|
||||
expiry_str = self.session['registration_cart_expiry'] |
||||
try: |
||||
expiry = datetime.datetime.fromisoformat(expiry_str) |
||||
return timezone.now() > expiry |
||||
except (ValueError, TypeError): |
||||
return True |
||||
|
||||
def reset_cart_expiry(self): |
||||
"""Reset the cart expiry time""" |
||||
expiry = timezone.now() + datetime.timedelta(minutes=self.CART_EXPIRY_MINUTES) |
||||
self.session['registration_cart_expiry'] = expiry.isoformat() |
||||
self.session.modified = True |
||||
|
||||
def get_tournament_id(self): |
||||
"""Get the tournament ID associated with the current cart""" |
||||
return self.session.get('registration_tournament_id') |
||||
|
||||
def initialize_cart(self, tournament_id): |
||||
"""Initialize a new registration cart for a tournament""" |
||||
# Clear any existing cart |
||||
self.clear_cart() |
||||
|
||||
try: |
||||
tournament = Tournament.objects.get(id=tournament_id) |
||||
except Tournament.DoesNotExist: |
||||
return False, "Tournoi introuvable." |
||||
|
||||
# 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: |
||||
# Handle player data |
||||
if self.context['add_player_form'].names_is_valid(): |
||||
self._handle_valid_names(player_data) |
||||
else: |
||||
self._handle_invalid_names(licence_id, player_data) |
||||
|
||||
def handle_team_registration(self): |
||||
if not self.context['team_form'].is_valid(): |
||||
return |
||||
|
||||
if self.request.user.is_authenticated: |
||||
cleaned_data = self.context['team_form'].cleaned_data |
||||
mobile_number = cleaned_data.get('mobile_number') |
||||
self.request.user.phone = mobile_number |
||||
self.request.user.save() |
||||
tournament.reserved_spots += 1 |
||||
|
||||
tournament.save() |
||||
|
||||
# Set up the new cart |
||||
self.session['registration_cart_id'] = str(uuid.uuid4()) # Ensure it's a string |
||||
self.session['waiting_list_position'] = waiting_list_position |
||||
self.session['registration_tournament_id'] = str(tournament_id) # Ensure it's a string |
||||
self.session['registration_cart_players'] = [] |
||||
self.reset_cart_expiry() |
||||
self.session.modified = True |
||||
|
||||
return True, "Cart initialized successfully" |
||||
|
||||
def get_cart_data(self): |
||||
"""Get the data for the current registration cart""" |
||||
# Ensure cart players array exists |
||||
if 'registration_cart_players' not in self.session: |
||||
self.session['registration_cart_players'] = [] |
||||
self.session.modified = True |
||||
|
||||
# Ensure tournament ID exists |
||||
if 'registration_tournament_id' not in self.session: |
||||
# If no tournament ID but we have players, this is an inconsistency |
||||
if self.session.get('registration_cart_players'): |
||||
print("WARNING: Found players but no tournament ID - clearing players") |
||||
self.session['registration_cart_players'] = [] |
||||
self.session.modified = True |
||||
|
||||
# Get user phone if authenticated |
||||
user_phone = '' |
||||
if hasattr(self.request.user, 'phone'): |
||||
user_phone = self.request.user.phone |
||||
|
||||
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(), |
||||
'mobile_number': self.session.get('registration_mobile_number', user_phone) |
||||
} |
||||
|
||||
waiting_list_position = self.tournament.get_waiting_list_position() |
||||
# Debug: print the cart content |
||||
print(f"Cart data - Tournament ID: {cart_data['tournament_id']}") |
||||
print(f"Cart data - Players count: {len(cart_data['players'])}") |
||||
|
||||
team_registration = self.repository.create_team_registration( |
||||
self.tournament, |
||||
timezone.now().replace(microsecond=0) |
||||
) |
||||
return cart_data |
||||
|
||||
def add_player(self, player_data): |
||||
"""Add a player to the registration cart""" |
||||
if self.is_cart_expired(): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
# Get cart data |
||||
tournament_id = self.session.get('registration_tournament_id') |
||||
if not tournament_id: |
||||
return False, "Pas d'inscription active." |
||||
|
||||
# Get tournament |
||||
try: |
||||
tournament = Tournament.objects.get(id=tournament_id) |
||||
except Tournament.DoesNotExist: |
||||
return False, "Tournoi introuvable." |
||||
|
||||
# Get existing players directly from session |
||||
players = self.session.get('registration_cart_players', []) |
||||
|
||||
# Check if we've reached the team limit |
||||
if len(players) >= 2: # Assuming teams of 2 for padel |
||||
return False, "Nombre maximum de joueurs déjà ajouté." |
||||
|
||||
self.repository.create_player_registrations( |
||||
self.request, |
||||
team_registration, |
||||
self.request.session['team_registration'], |
||||
self.context['team_form'].cleaned_data |
||||
# Process player data |
||||
licence_id = player_data.get('licence_id', '').upper() if player_data.get('licence_id') else None |
||||
first_name = player_data.get('first_name', '') |
||||
last_name = player_data.get('last_name', '').upper() if player_data.get('last_name') else '' |
||||
|
||||
# Handle license validation logic |
||||
result = self._process_player_license( |
||||
tournament, licence_id, first_name, last_name, players, len(players) == 0 |
||||
) |
||||
if not result[0]: |
||||
return result # Return the error |
||||
|
||||
# If we got here, license validation passed |
||||
if licence_id: |
||||
# Get federation data |
||||
fed_data, found = get_player_name_from_csv(tournament.federal_category, licence_id) |
||||
if found and fed_data: |
||||
# Use federation data (including check for eligibility) |
||||
player_register_check = tournament.player_register_check(licence_id) |
||||
if player_register_check: |
||||
return False, ", ".join(player_register_check) |
||||
|
||||
# Update player data from federation data |
||||
player_data.update({ |
||||
'first_name': fed_data['first_name'], |
||||
'last_name': fed_data['last_name'], |
||||
'rank': fed_data['rank'], |
||||
'is_woman': fed_data['is_woman'], |
||||
'points': fed_data.get('points'), |
||||
'assimilation': fed_data.get('assimilation'), |
||||
'tournament_count': fed_data.get('tournament_count'), |
||||
'ligue_name': fed_data.get('ligue_name'), |
||||
'club_name': fed_data.get('club_name'), |
||||
'birth_year': fed_data.get('birth_year'), |
||||
'found_in_french_federation': True, |
||||
}) |
||||
elif tournament.license_is_required: |
||||
# License required but not found in federation data |
||||
return False, "La licence fournit n'a pas été trouvée dans la base FFT. Contactez le juge arbitre si cette licence est valide." |
||||
elif not first_name or not last_name: |
||||
# License not required or not found, but name is needed |
||||
return False, "Le prénom et le nom sont obligatoires pour les joueurs sans licence." |
||||
elif not tournament.license_is_required: |
||||
# License not required, check if name is provided |
||||
if not first_name or not last_name: |
||||
return False, "Le prénom et le nom sont obligatoires pour les joueurs sans licence." |
||||
|
||||
# Set default rank for players without a license |
||||
if player_data.get('rank') is None: |
||||
default_data, _ = get_player_name_from_csv(tournament.federal_category, None) |
||||
if default_data: |
||||
player_data['rank'] = default_data.get('rank') |
||||
player_data['is_woman'] = default_data.get('is_woman', False) |
||||
else: |
||||
# License is required but not provided |
||||
return False, "Le numéro de licence est obligatoire." |
||||
|
||||
# Add player to cart |
||||
players.append(player_data) |
||||
self.session['registration_cart_players'] = players |
||||
self.reset_cart_expiry() |
||||
self.session.modified = True |
||||
|
||||
return True, "Joueur ajouté avec succès." |
||||
|
||||
def _process_player_license(self, tournament, licence_id, first_name, last_name, players, is_first_player): |
||||
""" |
||||
Process and validate player license |
||||
Returns (True, None) if valid, (False, error_message) if invalid |
||||
""" |
||||
# Handle case where license is required |
||||
if tournament.license_is_required: |
||||
# If license is required but not provided |
||||
if not licence_id: |
||||
# First player (authentication check) or partner |
||||
user_message = "Le numéro de licence est obligatoire." if is_first_player else "Le numéro de licence de votre partenaire est obligatoire." |
||||
return False, user_message |
||||
|
||||
# Validate the license format |
||||
validator = LicenseValidator(licence_id) |
||||
if not validator.validate_license(): |
||||
return False, "Le numéro de licence est invalide, la lettre ne correspond pas." |
||||
|
||||
# Check if player is already registered in tournament |
||||
stripped_license = validator.stripped_license |
||||
if self._is_player_already_registered(stripped_license, tournament): |
||||
return False, "Un joueur avec ce numéro de licence est déjà inscrit dans une équipe." |
||||
|
||||
# Check if this is the authenticated user trying to register as first player |
||||
if self.request.user.is_authenticated and is_first_player and self.request.user.licence_id is None: |
||||
# Try to update the user's license ID in the database |
||||
try: |
||||
self.request.user.licence_id = validator.computed_licence_id |
||||
self.request.user.save() |
||||
self.request.user.refresh_from_db() |
||||
except: |
||||
return False, "Erreur lors de la mise à jour de votre licence: cette licence est déjà utilisée par un autre joueur." |
||||
|
||||
# Check for duplicate licenses in cart |
||||
existing_licenses = [p.get('licence_id') for p in players if p.get('licence_id')] |
||||
if licence_id and licence_id in existing_licenses: |
||||
return False, "Ce joueur est déjà dans l'équipe." |
||||
|
||||
return True, None |
||||
|
||||
def remove_player(self): |
||||
"""Remove the last player from the cart""" |
||||
if self.is_cart_expired(): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
players = self.session.get('registration_cart_players', []) |
||||
if not players: |
||||
return False, "Pas de joueur à supprimer." |
||||
|
||||
# Remove last player |
||||
players.pop() |
||||
self.session['registration_cart_players'] = players |
||||
self.reset_cart_expiry() |
||||
self.session.modified = True |
||||
|
||||
return True, "Joueur retiré." |
||||
|
||||
def update_contact_info(self, mobile_number=None): |
||||
"""Update contact info for the cart""" |
||||
if self.is_cart_expired(): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
if mobile_number is not None: |
||||
self.session['registration_mobile_number'] = mobile_number |
||||
|
||||
self.reset_cart_expiry() |
||||
self.session.modified = True |
||||
|
||||
return True, "Informations de contact mises à jour." |
||||
|
||||
def checkout(self): |
||||
"""Convert cart to an actual tournament registration""" |
||||
if self.is_cart_expired(): |
||||
return False, "Votre session d'inscription a expiré, veuillez réessayer." |
||||
|
||||
# Get cart data |
||||
cart_data = self.get_cart_data() |
||||
tournament_id = cart_data.get('tournament_id') |
||||
players = cart_data.get('players') |
||||
mobile_number = cart_data.get('mobile_number') |
||||
|
||||
# Validate cart data |
||||
if not tournament_id: |
||||
return False, "Aucun tournoi sélectionné." |
||||
|
||||
if not players: |
||||
return False, "Aucun joueur dans l'inscription." |
||||
|
||||
# Get tournament |
||||
try: |
||||
tournament = Tournament.objects.get(id=tournament_id) |
||||
except Tournament.DoesNotExist: |
||||
return False, "Tournoi introuvable." |
||||
|
||||
# Check minimum players |
||||
if len(players) < tournament.minimum_player_per_team: |
||||
return False, f"Vous avez besoin d'au moins {tournament.minimum_player_per_team} joueurs pour vous inscrire." |
||||
|
||||
# Create team registration |
||||
team_registration = TeamRegistration.objects.create( |
||||
tournament=tournament, |
||||
registration_date=timezone.now(), |
||||
walk_out=False |
||||
) |
||||
|
||||
if is_not_sqlite_backend(): |
||||
self.email_service.send_registration_confirmation( |
||||
self.request, |
||||
self.tournament, |
||||
team_registration, |
||||
waiting_list_position |
||||
# Create player registrations |
||||
for idx, player_data in enumerate(players): |
||||
PlayerRegistration.objects.create( |
||||
team_registration=team_registration, |
||||
first_name=player_data.get('first_name', ''), |
||||
last_name=player_data.get('last_name', '').upper(), |
||||
licence_id=player_data.get('licence_id'), |
||||
rank=player_data.get('rank'), |
||||
points=player_data.get('points'), |
||||
club_name=player_data.get('club_name'), |
||||
ligue_name=player_data.get('ligue_name'), |
||||
email=player_data.get('email'), |
||||
phone_number=player_data.get('phone'), |
||||
assimilation=player_data.get('assimilation'), |
||||
tournament_played=player_data.get('tournament_count'), |
||||
birthdate=str(player_data.get('birth_year', '')), |
||||
captain=(idx == 0), # First player is captain |
||||
registered_online=True, |
||||
registration_status='CONFIRMED' if self.session['waiting_list_position'] < 0 else 'WAITING' |
||||
) |
||||
|
||||
self.clear_session_data() |
||||
self.context['registration_successful'] = True |
||||
|
||||
def handle_get_request(self): |
||||
print("handle_get_request") |
||||
storage = get_messages(self.request) |
||||
# Iterate through the storage to clear it |
||||
for _ in storage: |
||||
pass |
||||
|
||||
self.context['add_player_form'] = AddPlayerForm() |
||||
self.context['team_form'] = self.initialize_team_form() |
||||
self.initialize_session_data() |
||||
|
||||
def add_player_to_session(self, player_data): |
||||
print("add_player_to_session", player_data) |
||||
if not self.request.session.get('team_registration'): |
||||
self.request.session['team_registration'] = [] |
||||
|
||||
self.request.session['team_registration'].append(player_data) |
||||
self.context['current_players'] = self.request.session.get('team_registration', []) |
||||
self.context['add_player_form'].first_tournament = False |
||||
self.context['add_player_form'].user_without_licence = False |
||||
self.request.session.modified = True |
||||
|
||||
def clear_session_data(self): |
||||
self.request.session['team_registration'] = [] |
||||
self.request.session.modified = True |
||||
|
||||
def initialize_team_form(self): |
||||
initial_data = {} |
||||
if self.request.user.is_authenticated: |
||||
initial_data = { |
||||
'email': self.request.user.email, |
||||
'mobile_number': self.request.user.phone, |
||||
} |
||||
return TournamentRegistrationForm(initial=initial_data) |
||||
|
||||
def initialize_session_data(self): |
||||
print("initialize_session_data") |
||||
self.request.session['team_registration'] = [] |
||||
if self.request.user.is_authenticated: |
||||
self._add_authenticated_user_to_session() |
||||
|
||||
def _add_authenticated_user_to_session(self): |
||||
if not self.request.user.licence_id: |
||||
self._handle_user_without_license() |
||||
return |
||||
|
||||
player_data = self._get_authenticated_user_data() |
||||
if player_data: |
||||
self.request.session['team_registration'].insert(0, player_data) |
||||
self.context['current_players'] = self.request.session.get('team_registration', []) |
||||
self.request.session.modified = True |
||||
|
||||
def _handle_user_without_license(self): |
||||
# Update user phone if provided |
||||
if self.request.user.is_authenticated and mobile_number: |
||||
self.request.user.phone = mobile_number |
||||
self.request.user.save(update_fields=['phone']) |
||||
|
||||
# Clear the cart |
||||
self.clear_cart() |
||||
tournament.reserved_spots = max(0, tournament.reserved_spots - 1) |
||||
tournament.save() |
||||
|
||||
return True, team_registration |
||||
|
||||
def clear_cart(self): |
||||
"""Clear the registration cart""" |
||||
keys_to_clear = [ |
||||
'registration_cart_id', |
||||
'team_registration_id', |
||||
'registration_tournament_id', |
||||
'registration_cart_players', |
||||
'registration_cart_expiry', |
||||
'registration_mobile_number' |
||||
] |
||||
|
||||
for key in keys_to_clear: |
||||
if key in self.session: |
||||
del self.session[key] |
||||
|
||||
self.session.modified = True |
||||
|
||||
def _is_player_already_registered(self, stripped_license, tournament): |
||||
"""Check if a player is already registered in the tournament""" |
||||
return PlayerRegistration.objects.filter( |
||||
team_registration__tournament=tournament, |
||||
licence_id__icontains=stripped_license, |
||||
team_registration__walk_out=False |
||||
).exists() |
||||
|
||||
def add_authenticated_user(self): |
||||
""" |
||||
Adds the authenticated user to the cart if they have a valid license. |
||||
Returns True if added, False otherwise. |
||||
""" |
||||
if not self.request.user.is_authenticated or not self.request.user.licence_id: |
||||
return False |
||||
|
||||
# Create player data for the authenticated user |
||||
player_data = { |
||||
'first_name': self.request.user.first_name, |
||||
'last_name': self.request.user.last_name.upper(), |
||||
'last_name': self.request.user.last_name, |
||||
'licence_id': self.request.user.licence_id, |
||||
'email': self.request.user.email, |
||||
'phone': self.request.user.phone |
||||
} |
||||
self.context['add_player_form'] = AddPlayerForm(initial=player_data) |
||||
self.context['add_player_form'].user_without_licence = True |
||||
self.request.session.modified = True |
||||
|
||||
def _get_authenticated_user_data(self): |
||||
user = self.request.user |
||||
validator = LicenseValidator(user.licence_id) |
||||
# Add the user to the cart |
||||
success, _ = self.add_player(player_data) |
||||
return success |
||||
|
||||
player_data = { |
||||
'first_name': user.first_name, |
||||
'last_name': user.last_name.upper(), |
||||
'email': user.email, |
||||
'phone': user.phone, |
||||
'licence_id': validator.computed_licence_id |
||||
} |
||||
|
||||
data, found = get_player_name_from_csv(self.tournament.federal_category, user.licence_id) |
||||
if found and data: |
||||
player_data.update({ |
||||
'rank': data['rank'], |
||||
'points': data.get('points'), |
||||
'assimilation': data.get('assimilation'), |
||||
'tournament_count': data.get('tournament_count'), |
||||
'ligue_name': data.get('ligue_name'), |
||||
'club_name': data.get('club_name'), |
||||
'birth_year': data.get('birth_year'), |
||||
'found_in_french_federation': True, |
||||
}) |
||||
|
||||
return player_data |
||||
|
||||
def _validate_license(self, licence_id): |
||||
print("Validating license...") |
||||
validator = LicenseValidator(licence_id) |
||||
|
||||
if validator.validate_license() is False and self.tournament.license_is_required: |
||||
if not licence_id: |
||||
message = ("Le numéro de licence est obligatoire." |
||||
if not self.request.session.get('team_registration', []) |
||||
else "Le numéro de licence de votre partenaire est obligatoire.") |
||||
messages.error(self.request, message) |
||||
else: |
||||
# computed_license_key = validator.computed_license_key |
||||
# messages.error(self.request, f"Le numéro de licence est invalide, la lettre ne correspond pas. {computed_license_key}") |
||||
messages.error(self.request, "Le numéro de licence est invalide, la lettre ne correspond pas.") |
||||
print("License validation failed") |
||||
return False |
||||
return True |
||||
# For backward compatibility with existing code that uses the function-based approach |
||||
def get_or_create_registration_cart_id(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.get_or_create_cart_id() |
||||
|
||||
def _is_duplicate_player(self, licence_id): |
||||
existing_players = [player['licence_id'] for player in self.request.session.get('team_registration', [])] |
||||
if licence_id in existing_players: |
||||
messages.error(self.request, "Ce joueur est déjà dans l'équipe.") |
||||
return True |
||||
return False |
||||
|
||||
def _is_already_registered(self, licence_id): |
||||
validator = LicenseValidator(licence_id) |
||||
if (validator.validate_license() and |
||||
self._license_already_registered(validator.stripped_license) and |
||||
self.tournament.license_is_required): |
||||
messages.error(self.request, "Un joueur avec ce numéro de licence est déjà inscrit dans une équipe.") |
||||
return True |
||||
return False |
||||
|
||||
def _handle_valid_names(self, player_data): |
||||
print("_handle_valid_names", player_data) |
||||
if player_data.get('rank') is None: |
||||
self._set_default_rank(player_data) |
||||
|
||||
self.add_player_to_session(player_data) |
||||
self.context['add_player_form'] = AddPlayerForm() |
||||
self.context['add_player_form'].first_tournament = False |
||||
|
||||
def _handle_invalid_names(self, licence_id, player_data): |
||||
data, found = get_player_name_from_csv(self.tournament.federal_category, licence_id) |
||||
print("_handle_invalid_names get_player_name_from_csv", data, found) |
||||
if found and data: |
||||
self._update_player_data_from_csv(player_data, data) |
||||
player_check = self._player_check(player_data) |
||||
if player_check == True: |
||||
self.add_player_to_session(player_data) |
||||
self.context['add_player_form'] = AddPlayerForm() |
||||
else: |
||||
return |
||||
else: |
||||
print("_handle_first_tournament_case") |
||||
self._handle_first_tournament_case(data) |
||||
|
||||
def _set_default_rank(self, player_data): |
||||
if self.request.session.get('last_rank') is None: |
||||
data, found = get_player_name_from_csv(self.tournament.federal_category, None) |
||||
if data: |
||||
self.request.session['last_rank'] = data['rank'] |
||||
self.request.session['is_woman'] = data['is_woman'] |
||||
self.request.session.modified = True |
||||
|
||||
player_data['rank'] = self.request.session.get('last_rank', None) |
||||
player_data['is_woman'] = self.request.session.get('is_woman', False) |
||||
|
||||
def _update_user_license(self, licence_id): |
||||
if not self.request.user.is_authenticated or not licence_id: |
||||
return False |
||||
def get_cart_expiry(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.get_cart_expiry() |
||||
|
||||
self.context['add_player_form'].user_without_licence = False |
||||
validator = LicenseValidator(licence_id) |
||||
|
||||
if validator.validate_license(): |
||||
computed_licence_id = validator.computed_licence_id |
||||
try: |
||||
self.request.user.licence_id = computed_licence_id |
||||
self.request.user.save() |
||||
self.request.user.refresh_from_db() |
||||
self.request.session.modified = True |
||||
return True |
||||
|
||||
except IntegrityError: |
||||
# Handle the duplicate license error |
||||
error_msg = f"Ce numéro de licence ({computed_licence_id}) est déjà utilisé par un autre joueur." |
||||
messages.error(self.request, error_msg) |
||||
return False |
||||
|
||||
def _update_player_data_from_csv(self, player_data, csv_data): |
||||
print("_update_player_data_from_csv", player_data, csv_data) |
||||
player_data.update({ |
||||
'first_name': csv_data['first_name'], |
||||
'last_name': csv_data['last_name'], |
||||
'rank': csv_data['rank'], |
||||
'is_woman': csv_data['is_woman'], |
||||
'points': csv_data.get('points'), |
||||
'assimilation': csv_data.get('assimilation'), |
||||
'tournament_count': csv_data.get('tournament_count'), |
||||
'ligue_name': csv_data.get('ligue_name'), |
||||
'club_name': csv_data.get('club_name'), |
||||
'birth_year': csv_data.get('birth_year'), |
||||
'found_in_french_federation': True, |
||||
'email': None, |
||||
'phone': None, |
||||
}) |
||||
|
||||
User = get_user_model() |
||||
|
||||
# Get the license ID from player_data |
||||
licence_id = player_data.get('licence_id') |
||||
validator = LicenseValidator(licence_id) |
||||
if validator.validate_license(): |
||||
try: |
||||
# Try to find a user with matching license |
||||
user_with_same_license = User.objects.get(licence_id__iexact=validator.computed_licence_id) |
||||
|
||||
# If found, update the email and phone |
||||
if user_with_same_license: |
||||
player_data.update({ |
||||
'email': user_with_same_license.email, |
||||
'phone': user_with_same_license.phone |
||||
}) |
||||
print(f"Found user with license {licence_id}, updated email and phone") |
||||
except User.DoesNotExist: |
||||
# No user found with this license, continue with None email and phone |
||||
pass |
||||
|
||||
def _handle_first_tournament_case(self, data): |
||||
print("_handle_first_tournament_case", data) |
||||
if data: |
||||
self.request.session['last_rank'] = data['rank'] |
||||
self.request.session['is_woman'] = data['is_woman'] |
||||
self.request.session.modified = True |
||||
|
||||
self.context['add_player_form'].first_tournament = True |
||||
|
||||
if not self.context['add_player_form'].names_is_valid(): |
||||
message = ("Pour confirmer votre inscription votre prénom et votre nom sont obligatoires." |
||||
if not self.request.session.get('team_registration', []) |
||||
else "Pour rajouter un partenaire, son prénom et son nom sont obligatoires.") |
||||
messages.error(self.request, message) |
||||
|
||||
def _player_check(self, player_data): |
||||
licence_id = player_data['licence_id'].upper() |
||||
validator = LicenseValidator(licence_id) |
||||
is_license_valid = validator.validate_license() |
||||
|
||||
player_register_check = self.tournament.player_register_check(licence_id) |
||||
if is_license_valid and player_register_check is not None: |
||||
for message in player_register_check: |
||||
messages.error(self.request, message) |
||||
return False |
||||
def is_cart_expired(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.is_cart_expired() |
||||
|
||||
return True |
||||
def reset_cart_expiry(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
cart_manager.reset_cart_expiry() |
||||
|
||||
def _license_already_registered(self, stripped_license): |
||||
return PlayerRegistration.objects.filter( |
||||
team_registration__tournament=self.tournament, |
||||
licence_id__icontains=stripped_license, |
||||
team_registration__walk_out=False |
||||
).exists() |
||||
def get_tournament_from_cart(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.get_tournament_id() |
||||
|
||||
def initialize_registration_cart(request, tournament_id): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.initialize_cart(tournament_id) |
||||
|
||||
def get_registration_cart_data(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.get_cart_data() |
||||
|
||||
def add_player_to_cart(request, player_data): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.add_player(player_data) |
||||
|
||||
def remove_player_from_cart(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.remove_player() |
||||
|
||||
def update_cart_contact_info(request, mobile_number=None): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.update_contact_info(mobile_number) |
||||
|
||||
def checkout_registration_cart(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.checkout() |
||||
|
||||
def clear_registration_cart(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
cart_manager.clear_cart() |
||||
|
||||
def add_authenticated_user_to_cart(request): |
||||
cart_manager = RegistrationCartManager(request) |
||||
return cart_manager.add_authenticated_user() |
||||
|
||||
Loading…
Reference in new issue