parent
33c084ba0e
commit
a321c4c154
@ -0,0 +1,346 @@ |
|||||||
|
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) |
||||||
|
|
||||||
|
# Set up the new cart |
||||||
|
request.session['registration_cart_id'] = str(uuid.uuid4()) |
||||||
|
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'), |
||||||
|
'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 tournament.get_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) |
||||||
|
|
||||||
|
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 |
||||||
Loading…
Reference in new issue