203 lines
8.5 KiB
Python
203 lines
8.5 KiB
Python
"""Evaluation routes for assessing player performance during tryouts.
|
|
|
|
This module handles player evaluation creation, management, and viewing.
|
|
"""
|
|
|
|
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, Evaluation, TryoutRegistration
|
|
from sqlalchemy import func
|
|
|
|
evaluations_bp = Blueprint('evaluations', __name__, url_prefix='/evaluations')
|
|
|
|
|
|
@evaluations_bp.route('')
|
|
@login_required
|
|
def list_evaluations():
|
|
"""List all evaluations accessible to the current user.
|
|
|
|
President: All evaluations with player score summaries.
|
|
Evaluators (coach/manager): Their given evaluations.
|
|
Players: Their received evaluations.
|
|
|
|
Returns:
|
|
Response: Rendered evaluations list template.
|
|
"""
|
|
user = current_user
|
|
|
|
if user.role == 'president':
|
|
evaluations = Evaluation.query.order_by(Evaluation.created_at.desc()).all()
|
|
avg_scores = db.session.query(
|
|
Evaluation.player_id,
|
|
func.count(Evaluation.id).label('eval_count'),
|
|
func.avg(Evaluation.overall_score).label('avg_score')
|
|
).group_by(Evaluation.player_id).all()
|
|
player_scores = {}
|
|
for row in avg_scores:
|
|
p = User.query.get(row.player_id)
|
|
if p:
|
|
player_scores[p.id] = {'player': p, 'count': row.eval_count, 'avg': round(row.avg_score, 1) if row.avg_score else 0}
|
|
|
|
elif user.can_evaluate():
|
|
evaluations = Evaluation.query.filter_by(evaluator_id=user.id).order_by(Evaluation.created_at.desc()).all()
|
|
player_scores = {}
|
|
else:
|
|
evaluations = Evaluation.query.filter_by(player_id=user.id).order_by(Evaluation.created_at.desc()).all()
|
|
player_scores = {}
|
|
|
|
return render_template('pages/evaluations.html', evaluations=evaluations, player_scores=player_scores)
|
|
|
|
|
|
@evaluations_bp.route('/<int:tryout_id>/<int:player_id>', methods=['GET', 'POST'])
|
|
@login_required
|
|
def evaluate_player(tryout_id, player_id):
|
|
"""Evaluate a specific player in a tryout.
|
|
|
|
GET: Render the evaluation form with any existing evaluation.
|
|
POST: Create or update the evaluation for the player.
|
|
|
|
Args:
|
|
tryout_id: The ID of the tryout.
|
|
player_id: The ID of the player to evaluate.
|
|
|
|
Returns:
|
|
Response: Evaluation form or redirect to tryout view.
|
|
"""
|
|
if not current_user.can_evaluate():
|
|
flash('You do not have permission to evaluate players.', 'danger')
|
|
return redirect(url_for('main.dashboard'))
|
|
|
|
tryout = Tryout.query.get_or_404(tryout_id)
|
|
|
|
# Check if user has permission to evaluate players in this tryout
|
|
if not current_user.can_manage_this_tryout(tryout):
|
|
flash('You do not have permission to evaluate players in this tryout.', 'danger')
|
|
return redirect(url_for('tryouts.list_tryouts'))
|
|
|
|
player = User.query.get_or_404(player_id)
|
|
|
|
if player.role != 'player':
|
|
flash('Can only evaluate players.', 'danger')
|
|
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
|
|
|
existing_eval = Evaluation.query.filter_by(
|
|
tryout_id=tryout_id,
|
|
player_id=player_id,
|
|
evaluator_id=current_user.id
|
|
).first()
|
|
|
|
if request.method == 'POST':
|
|
mecanics = request.form.get('mecanics_score')
|
|
cohesion = request.form.get('cohesion_score')
|
|
communication = request.form.get('communication_score')
|
|
gamesense = request.form.get('gamesense_score')
|
|
versatility = request.form.get('versatility_score')
|
|
discipline = request.form.get('discipline_score')
|
|
analysis = request.form.get('analysis_score')
|
|
sport_ethics = request.form.get('sport_ethics_score')
|
|
mental = request.form.get('mental_score')
|
|
comments = request.form.get('comments')
|
|
position = request.form.get('position_recommendation')
|
|
|
|
scores = []
|
|
if mecanics: scores.append(int(mecanics))
|
|
if cohesion: scores.append(int(cohesion))
|
|
if communication: scores.append(int(communication))
|
|
if gamesense: scores.append(int(gamesense))
|
|
if versatility: scores.append(int(versatility))
|
|
if discipline: scores.append(int(discipline))
|
|
if analysis: scores.append(int(analysis))
|
|
if sport_ethics: scores.append(int(sport_ethics))
|
|
if mental: scores.append(int(mental))
|
|
|
|
overall = sum(scores) / len(scores) if scores else None
|
|
|
|
if existing_eval:
|
|
existing_eval.mecanics_score = int(mecanics) if mecanics else None
|
|
existing_eval.cohesion_score = int(cohesion) if cohesion else None
|
|
existing_eval.communication_score = int(communication) if communication else None
|
|
existing_eval.gamesense_score = int(gamesense) if gamesense else None
|
|
existing_eval.versatility_score = int(versatility) if versatility else None
|
|
existing_eval.discipline_score = int(discipline) if discipline else None
|
|
existing_eval.analysis_score = int(analysis) if analysis else None
|
|
existing_eval.sport_ethics_score = int(sport_ethics) if sport_ethics else None
|
|
existing_eval.mental_score = int(mental) if mental else None
|
|
existing_eval.overall_score = overall
|
|
existing_eval.comments = comments
|
|
existing_eval.position_recommendation = position
|
|
flash('Evaluation updated!', 'success')
|
|
else:
|
|
evaluation = Evaluation(
|
|
tryout_id=tryout_id,
|
|
player_id=player_id,
|
|
evaluator_id=current_user.id,
|
|
mecanics_score=int(mecanics) if mecanics else None,
|
|
cohesion_score=int(cohesion) if cohesion else None,
|
|
communication_score=int(communication) if communication else None,
|
|
gamesense_score=int(gamesense) if gamesense else None,
|
|
versatility_score=int(versatility) if versatility else None,
|
|
discipline_score=int(discipline) if discipline else None,
|
|
analysis_score=int(analysis) if analysis else None,
|
|
sport_ethics_score=int(sport_ethics) if sport_ethics else None,
|
|
mental_score=int(mental) if mental else None,
|
|
overall_score=overall,
|
|
comments=comments,
|
|
position_recommendation=position
|
|
)
|
|
db.session.add(evaluation)
|
|
flash('Evaluation submitted successfully!', 'success')
|
|
|
|
db.session.commit()
|
|
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
|
|
|
evaluators = None
|
|
if current_user.role == 'president':
|
|
all_evaluations = Evaluation.query.filter_by(tryout_id=tryout_id, player_id=player_id).all()
|
|
evaluators = [{'evaluator': User.query.get(e.evaluator_id), 'eval': e} for e in all_evaluations]
|
|
|
|
return render_template('pages/evaluate_player.html',
|
|
tryout=tryout,
|
|
player=player,
|
|
existing_eval=existing_eval,
|
|
evaluators=evaluators)
|
|
|
|
|
|
@evaluations_bp.route('/<int:tryout_id>/players')
|
|
@login_required
|
|
def players_to_evaluate(tryout_id):
|
|
"""List players that need evaluation in a specific tryout.
|
|
|
|
Shows all registered players and marks which ones have already been evaluated
|
|
by the current user.
|
|
|
|
Args:
|
|
tryout_id: The ID of the tryout.
|
|
|
|
Returns:
|
|
Response: Rendered players-to-evaluate template.
|
|
"""
|
|
if not current_user.can_evaluate():
|
|
flash('Permission denied.', 'danger')
|
|
return redirect(url_for('main.dashboard'))
|
|
|
|
tryout = Tryout.query.get_or_404(tryout_id)
|
|
|
|
# Check if user has permission to evaluate players in this tryout
|
|
if not current_user.can_manage_this_tryout(tryout):
|
|
flash('You do not have permission to evaluate players in this tryout.', 'danger')
|
|
return redirect(url_for('tryouts.list_tryouts'))
|
|
|
|
registrations = TryoutRegistration.query.filter_by(tryout_id=tryout_id).all()
|
|
players = []
|
|
for reg in registrations:
|
|
p = User.query.get(reg.player_id)
|
|
if p and p.role == 'player':
|
|
existing = Evaluation.query.filter_by(
|
|
tryout_id=tryout_id,
|
|
player_id=p.id,
|
|
evaluator_id=current_user.id
|
|
).first()
|
|
players.append({'player': p, 'evaluated': existing is not None, 'registration': reg})
|
|
|
|
return render_template('pages/players_to_evaluate.html', tryout=tryout, players=players) |