From 1549fbaef357e0d81b448d285304af6b001a96f2 Mon Sep 17 00:00:00 2001 From: cedrick2711 Date: Tue, 25 Aug 2026 14:03:24 -0400 Subject: [PATCH] fix merge conflict --- app/routes/tryouts.py | 50 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/app/routes/tryouts.py b/app/routes/tryouts.py index e537463..38f7f0c 100644 --- a/app/routes/tryouts.py +++ b/app/routes/tryouts.py @@ -30,6 +30,7 @@ from app.models import ( Tryout, TryoutRegistration, User, + AppSettings, ) from app.time_utils import utc_now_naive from app.validators import ( @@ -49,6 +50,17 @@ def can_manage(): return isinstance(current_user, (Admin, Manager)) +def tryouts_locked(): + """Return True when tryouts are globally closed to coaches/managers. + + Admins are always allowed to bypass the lock. Coaches and managers can + only make changes when the global tryout switch is open. + """ + if isinstance(current_user, Admin): + return False + return not AppSettings.get_bool('tryouts_open', default=True) + + def tryout_form_payload(): """The tryout form, shaped for marshmallow (ARCH-005).""" return form_payload(list_fields=('coach_ids', 'manager_ids'), optional_blank=()) @@ -131,6 +143,10 @@ def create_tryout(): flash(_('You do not have permission to create tryouts.'), 'danger') return redirect(url_for('tryouts.list_tryouts')) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.list_tryouts')) + org_teams = OrgTeam.query.order_by(OrgTeam.name).all() managers = ( User.query.filter_by(role='manager', is_active_account=True).order_by(User.username).all() @@ -191,6 +207,10 @@ def edit_tryout(tryout_id): flash(_('You do not have permission to edit this tryout.'), 'danger') return redirect(url_for('tryouts.list_tryouts')) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout.id)) + if tryout.is_ended: flash(_('This tryout has ended and can no longer be modified.'), 'danger') return redirect(url_for('tryouts.view_tryout', tryout_id=tryout.id)) @@ -231,7 +251,7 @@ def edit_tryout(tryout_id): # Only update staff lists when the form explicitly sends them. # An absent checkbox group (all unchecked or JS failed) means - # \"don't change\", not \"remove everyone\". + # "don't change", not "remove everyone". if 'coach_ids' in request.form: tryout.coaches = coaches_from_ids(data['coach_ids']) if 'manager_ids' in request.form: @@ -482,6 +502,9 @@ def update_status(tryout_id): if not current_user.can_manage_this_tryout(tryout): flash(_('Permission denied.'), 'danger') return redirect(url_for('tryouts.list_tryouts')) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) try: data = TryoutStatusSchema().load(form_payload(list_fields=())) except ValidationError as err: @@ -503,6 +526,10 @@ def update_registration_status(tryout_id, player_id): flash(_('Permission denied.'), 'danger') return redirect(url_for('tryouts.list_tryouts')) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + registration = TryoutRegistration.query.filter_by( tryout_id=tryout_id, player_id=player_id ).first_or_404() @@ -526,6 +553,9 @@ def register_player(tryout_id): if not current_user.can_manage_this_tryout(tryout): flash(_('Permission denied.'), 'danger') return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) try: data = PlayerSelectionSchema().load(form_payload()) except ValidationError as err: @@ -574,6 +604,10 @@ def remove_player(tryout_id, player_id): flash(_('Permission denied.'), 'danger') return redirect(url_for('tryouts.list_tryouts')) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + player = db.get_or_404(User, player_id) registration = TryoutRegistration.query.filter_by( @@ -610,6 +644,10 @@ def create_team(tryout_id): flash(_('Permission denied.'), 'danger') return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + try: data = TryoutTeamSchema().load(form_payload(list_fields=())) except ValidationError as err: @@ -633,6 +671,10 @@ def add_to_team(tryout_id, team_id): flash(_('Permission denied.'), 'danger') return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + # The two ids arrive independently in the URL. Without this check, being # allowed to manage tryout A was enough to modify a team belonging to # tryout B, since only the tryout was authorised. @@ -675,6 +717,10 @@ def delete_tryout(tryout_id): flash(_('You do not have permission to delete this tryout.'), 'danger') return redirect(url_for('tryouts.list_tryouts')) + if tryouts_locked(): + flash(_('Tryouts are currently closed. An admin must open tryouts before changes can be made.'), 'danger') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + match_ids = [m.id for m in Match.query.filter_by(tryout_id=tryout_id).all()] team_ids = [t.id for t in Team.query.filter_by(tryout_id=tryout_id).all()] @@ -709,4 +755,4 @@ def delete_tryout(tryout_id): db.session.delete(tryout) db.session.commit() flash(_('Tryout deleted successfully.'), 'success') - return redirect(url_for('tryouts.list_tryouts')) + return redirect(url_for('tryouts.list_tryouts')) \ No newline at end of file