first commit
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
from flask import Blueprint, render_template, redirect, url_for, flash, request
|
||||
from flask_login import login_required, current_user
|
||||
from extensions import db
|
||||
from models import User, Tryout, TryoutRegistration, Evaluation, Team, TeamMember, OrgTeam
|
||||
from datetime import datetime
|
||||
|
||||
tryouts_bp = Blueprint('tryouts', __name__, url_prefix='/tryouts')
|
||||
|
||||
def can_manage():
|
||||
return current_user.role in ['president', 'manager']
|
||||
|
||||
@tryouts_bp.route('')
|
||||
@login_required
|
||||
def list_tryouts():
|
||||
if current_user.role == 'president':
|
||||
tryouts = Tryout.query.order_by(Tryout.date.desc()).all()
|
||||
elif current_user.role == 'manager':
|
||||
tryouts = Tryout.query.filter_by(created_by=current_user.id).order_by(Tryout.date.desc()).all()
|
||||
elif current_user.role == 'coach':
|
||||
# Coaches see tryouts targeting their org team
|
||||
org_team = OrgTeam.query.filter_by(coach_id=current_user.id).first()
|
||||
if org_team:
|
||||
tryouts = Tryout.query.filter_by(target_org_team_id=org_team.id).order_by(Tryout.date.desc()).all()
|
||||
else:
|
||||
tryouts = []
|
||||
elif current_user.role == 'player':
|
||||
tryouts = Tryout.query.filter(Tryout.status.in_(['upcoming', 'in_progress'])).order_by(Tryout.date.desc()).all()
|
||||
else:
|
||||
tryouts = Tryout.query.order_by(Tryout.date.desc()).all()
|
||||
return render_template('pages/tryouts.html', tryouts=tryouts, now=datetime.utcnow())
|
||||
|
||||
@tryouts_bp.route('/create', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def create_tryout():
|
||||
if not can_manage():
|
||||
flash('You do not have permission to create tryouts.', 'danger')
|
||||
return redirect(url_for('tryouts.list_tryouts'))
|
||||
|
||||
org_teams = OrgTeam.query.order_by(OrgTeam.name).all()
|
||||
|
||||
if request.method == 'POST':
|
||||
title = request.form.get('title')
|
||||
description = request.form.get('description')
|
||||
date_str = request.form.get('date')
|
||||
location = request.form.get('location')
|
||||
max_players = request.form.get('max_players')
|
||||
target_org_team_id = request.form.get('target_org_team_id')
|
||||
|
||||
try:
|
||||
date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
|
||||
except (ValueError, TypeError):
|
||||
flash('Invalid date format.', 'danger')
|
||||
return render_template('pages/create_tryout.html', org_teams=org_teams)
|
||||
|
||||
tryout = Tryout(
|
||||
title=title,
|
||||
description=description,
|
||||
date=date_obj,
|
||||
location=location,
|
||||
max_players=int(max_players) if max_players else None,
|
||||
created_by=current_user.id,
|
||||
status='upcoming',
|
||||
target_org_team_id=int(target_org_team_id) if target_org_team_id else None
|
||||
)
|
||||
db.session.add(tryout)
|
||||
db.session.commit()
|
||||
flash('Tryout created successfully!', 'success')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout.id))
|
||||
|
||||
return render_template('pages/create_tryout.html', org_teams=org_teams)
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>/edit', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_tryout(tryout_id):
|
||||
tryout = Tryout.query.get_or_404(tryout_id)
|
||||
|
||||
# Permission: president can edit any; manager can edit own; coach can edit if it targets their team
|
||||
if current_user.role == 'president':
|
||||
pass # allowed
|
||||
elif current_user.role == 'manager' and tryout.created_by == current_user.id:
|
||||
pass # allowed
|
||||
elif current_user.role == 'coach':
|
||||
org_team = OrgTeam.query.filter_by(coach_id=current_user.id).first()
|
||||
if not org_team or tryout.target_org_team_id != org_team.id:
|
||||
flash('You do not have permission to edit this tryout.', 'danger')
|
||||
return redirect(url_for('tryouts.list_tryouts'))
|
||||
else:
|
||||
flash('You do not have permission to edit this tryout.', 'danger')
|
||||
return redirect(url_for('tryouts.list_tryouts'))
|
||||
|
||||
org_teams = OrgTeam.query.order_by(OrgTeam.name).all()
|
||||
|
||||
if request.method == 'POST':
|
||||
title = request.form.get('title')
|
||||
description = request.form.get('description')
|
||||
date_str = request.form.get('date')
|
||||
location = request.form.get('location')
|
||||
max_players = request.form.get('max_players')
|
||||
target_org_team_id = request.form.get('target_org_team_id')
|
||||
|
||||
try:
|
||||
date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
|
||||
except (ValueError, TypeError):
|
||||
flash('Invalid date format.', 'danger')
|
||||
return render_template('pages/edit_tryout.html', tryout=tryout, org_teams=org_teams)
|
||||
|
||||
tryout.title = title
|
||||
tryout.description = description
|
||||
tryout.date = date_obj
|
||||
tryout.location = location
|
||||
tryout.max_players = int(max_players) if max_players else None
|
||||
tryout.target_org_team_id = int(target_org_team_id) if target_org_team_id else None
|
||||
db.session.commit()
|
||||
flash('Tryout updated successfully!', 'success')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout.id))
|
||||
|
||||
return render_template('pages/edit_tryout.html', tryout=tryout, org_teams=org_teams)
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>')
|
||||
@login_required
|
||||
def view_tryout(tryout_id):
|
||||
tryout = Tryout.query.get_or_404(tryout_id)
|
||||
registrations = TryoutRegistration.query.filter_by(tryout_id=tryout_id).all()
|
||||
registered_players = [User.query.get(r.player_id) for r in registrations if r.player_id]
|
||||
evaluations = Evaluation.query.filter_by(tryout_id=tryout_id).all()
|
||||
|
||||
evaluator_ids = set(e.evaluator_id for e in evaluations)
|
||||
player_ids_with_eval = set(e.player_id for e in evaluations)
|
||||
|
||||
# Check if current user has evaluated each player
|
||||
player_eval_status = {}
|
||||
if current_user.can_evaluate():
|
||||
for p in registered_players:
|
||||
existing = Evaluation.query.filter_by(
|
||||
tryout_id=tryout_id,
|
||||
player_id=p.id,
|
||||
evaluator_id=current_user.id
|
||||
).first()
|
||||
player_eval_status[p.id] = existing is not None
|
||||
|
||||
is_registered = TryoutRegistration.query.filter_by(
|
||||
tryout_id=tryout_id, player_id=current_user.id
|
||||
).first() is not None
|
||||
|
||||
teams = Team.query.filter_by(tryout_id=tryout_id).all()
|
||||
team_data = []
|
||||
for team in teams:
|
||||
members = TeamMember.query.filter_by(team_id=team.id).all()
|
||||
team_data.append({
|
||||
'team': team,
|
||||
'members': [{'player': User.query.get(m.player_id), 'position': m.position} for m in members]
|
||||
})
|
||||
|
||||
# Determine if current user can edit this tryout
|
||||
can_edit = False
|
||||
if current_user.role == 'president':
|
||||
can_edit = True
|
||||
elif current_user.role == 'manager' and tryout.created_by == current_user.id:
|
||||
can_edit = True
|
||||
elif current_user.role == 'coach':
|
||||
org_team = OrgTeam.query.filter_by(coach_id=current_user.id).first()
|
||||
if org_team and tryout.target_org_team_id == org_team.id:
|
||||
can_edit = True
|
||||
|
||||
# Get all players (for manager registration dropdown)
|
||||
all_players = User.query.filter_by(role='player').order_by(User.full_name).all()
|
||||
|
||||
return render_template('pages/view_tryout.html',
|
||||
tryout=tryout,
|
||||
registered_players=registered_players,
|
||||
evaluations=evaluations,
|
||||
player_eval_status=player_eval_status,
|
||||
is_registered=is_registered,
|
||||
registrations=registrations,
|
||||
team_data=team_data,
|
||||
can_edit=can_edit,
|
||||
all_players=all_players,
|
||||
now=datetime.utcnow())
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>/register', methods=['POST'])
|
||||
@login_required
|
||||
def register_for_tryout(tryout_id):
|
||||
tryout = Tryout.query.get_or_404(tryout_id)
|
||||
if current_user.role != 'player':
|
||||
flash('Only players can register for tryouts.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
if tryout.status not in ['upcoming', 'in_progress']:
|
||||
flash('This tryout is not accepting registrations.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
existing = TryoutRegistration.query.filter_by(tryout_id=tryout_id, player_id=current_user.id).first()
|
||||
if existing:
|
||||
flash('You are already registered for this tryout.', 'info')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
if tryout.max_players:
|
||||
count = TryoutRegistration.query.filter_by(tryout_id=tryout_id).count()
|
||||
if count >= tryout.max_players:
|
||||
flash('This tryout is full.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
registration = TryoutRegistration(tryout_id=tryout_id, player_id=current_user.id)
|
||||
db.session.add(registration)
|
||||
db.session.commit()
|
||||
flash('Successfully registered for tryout!', 'success')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>/status', methods=['POST'])
|
||||
@login_required
|
||||
def update_status(tryout_id):
|
||||
if not can_manage():
|
||||
flash('Permission denied.', 'danger')
|
||||
return redirect(url_for('tryouts.list_tryouts'))
|
||||
|
||||
tryout = Tryout.query.get_or_404(tryout_id)
|
||||
new_status = request.form.get('status')
|
||||
if new_status in ['upcoming', 'in_progress', 'completed']:
|
||||
tryout.status = new_status
|
||||
db.session.commit()
|
||||
flash(f'Tryout status updated to {new_status}.', 'success')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>/registration/<int:player_id>/status', methods=['POST'])
|
||||
@login_required
|
||||
def update_registration_status(tryout_id, player_id):
|
||||
if not can_manage():
|
||||
flash('Permission denied.', 'danger')
|
||||
return redirect(url_for('tryouts.list_tryouts'))
|
||||
|
||||
registration = TryoutRegistration.query.filter_by(tryout_id=tryout_id, player_id=player_id).first_or_404()
|
||||
new_status = request.form.get('status')
|
||||
if new_status in ['registered', 'attended', 'no_show']:
|
||||
registration.status = new_status
|
||||
db.session.commit()
|
||||
flash('Registration status updated.', 'success')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>/register_player', methods=['POST'])
|
||||
@login_required
|
||||
def register_player(tryout_id):
|
||||
if not can_manage():
|
||||
flash('Permission denied.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
tryout = Tryout.query.get_or_404(tryout_id)
|
||||
player_id = request.form.get('player_id')
|
||||
|
||||
if not player_id:
|
||||
flash('Please select a player.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
player = User.query.get_or_404(int(player_id))
|
||||
if player.role != 'player':
|
||||
flash('Can only register players.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
existing = TryoutRegistration.query.filter_by(tryout_id=tryout_id, player_id=player.id).first()
|
||||
if existing:
|
||||
flash(f'{player.full_name} is already registered for this tryout.', 'info')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
if tryout.max_players:
|
||||
count = TryoutRegistration.query.filter_by(tryout_id=tryout_id).count()
|
||||
if count >= tryout.max_players:
|
||||
flash('This tryout is full.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
registration = TryoutRegistration(tryout_id=tryout_id, player_id=player.id)
|
||||
db.session.add(registration)
|
||||
db.session.commit()
|
||||
flash(f'{player.full_name} registered for tryout!', 'success')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>/team/create', methods=['POST'])
|
||||
@login_required
|
||||
def create_team(tryout_id):
|
||||
if not can_manage():
|
||||
flash('Permission denied.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
team_name = request.form.get('team_name')
|
||||
if team_name:
|
||||
team = Team(tryout_id=tryout_id, name=team_name, created_by=current_user.id)
|
||||
db.session.add(team)
|
||||
db.session.commit()
|
||||
flash(f'Team "{team_name}" created!', 'success')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
@tryouts_bp.route('/<int:tryout_id>/team/<int:team_id>/add', methods=['POST'])
|
||||
@login_required
|
||||
def add_to_team(tryout_id, team_id):
|
||||
if not can_manage():
|
||||
flash('Permission denied.', 'danger')
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
|
||||
player_id = request.form.get('player_id')
|
||||
position = request.form.get('position', '')
|
||||
team = Team.query.get_or_404(team_id)
|
||||
|
||||
existing = TeamMember.query.filter_by(team_id=team_id, player_id=player_id).first()
|
||||
if existing:
|
||||
flash('Player is already on this team.', 'info')
|
||||
else:
|
||||
member = TeamMember(team_id=team_id, player_id=int(player_id), position=position)
|
||||
db.session.add(member)
|
||||
db.session.commit()
|
||||
flash('Player added to team!', 'success')
|
||||
|
||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||
Reference in New Issue
Block a user