From 79f76d2b75c98d2747a556984b76a4ccfb62365e Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Sat, 25 Sep 2021 00:04:51 +0200
Subject: [PATCH] =?UTF-8?q?Hierarchie:=20Spr=C3=A1va=20=C3=BA=C4=8Dastn?=
 =?UTF-8?q?=C3=ADk=C5=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 mo/web/org_contest.py | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 446992a1..7b8379ba 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -7,6 +7,7 @@ from sqlalchemy import func, and_, select
 from sqlalchemy.orm import joinedload, aliased
 from sqlalchemy.orm.query import Query
 from sqlalchemy.dialects.postgresql import insert as pgsql_insert
+import sqlalchemy.sql.schema
 from typing import Any, List, Tuple, Optional, Dict
 import urllib.parse
 import werkzeug.exceptions
@@ -483,8 +484,11 @@ def org_generic_import(round_id: Optional[int] = None, ct_id: Optional[int] = No
 @app.route('/org/contest/c/<int:ct_id>/site/<int:site_id>/participants/emails', endpoint="org_generic_list_emails")
 @app.route('/org/contest/r/<int:round_id>/participants', methods=('GET', 'POST'))
 @app.route('/org/contest/r/<int:round_id>/participants/emails', endpoint="org_generic_list_emails")
-def org_generic_list(round_id: Optional[int] = None, ct_id: Optional[int] = None, site_id: Optional[int] = None):
-    ctx = get_context(round_id=round_id, ct_id=ct_id, site_id=site_id, right_needed=Right.view_contestants)
+@app.route('/org/contest/r/<int:round_id>/h/<int:hier_id>/participants', methods=('GET', 'POST'))
+@app.route('/org/contest/r/<int:round_id>/h/<int:hier_id>/participants/emails', endpoint="org_generic_list_emails")
+def org_generic_list(round_id: Optional[int] = None, hier_id: Optional[int] = None,
+                     ct_id: Optional[int] = None, site_id: Optional[int] = None):
+    ctx = get_context(round_id=round_id, hier_id=hier_id, ct_id=ct_id, site_id=site_id, right_needed=Right.view_contestants)
     round, contest = ctx.master_round, ctx.master_contest
     rr = ctx.rights
     can_edit = rr.have_right(Right.manage_contest) and request.endpoint != 'org_generic_list_emails'
@@ -495,7 +499,7 @@ def org_generic_list(round_id: Optional[int] = None, ct_id: Optional[int] = None
         filter.validate()
 
     query = get_contestants_query(
-        round=round, contest=contest, site=ctx.site,
+        ctx=ctx,
         school=filter.school.place,
         contest_place=filter.contest_place.place,
         participation_place=filter.participation_place.place,
@@ -550,8 +554,7 @@ contest_list_columns = (
 
 
 def get_contestants_query(
-        round: db.Round, contest: Optional[db.Contest] = None,
-        site: Optional[db.Place] = None,
+        ctx: Context,
         contest_place: Optional[db.Place] = None,
         participation_place: Optional[db.Place] = None,
         participation_state: Optional[db.PartState] = None,
@@ -561,15 +564,18 @@ def get_contestants_query(
              .select_from(db.Participation)
              .join(db.Participant, db.Participant.user_id == db.Participation.user_id)
              .join(db.User, db.User.user_id == db.Participation.user_id)
-             .filter(db.Participant.year == round.year))
-    if contest:
-        query = query.join(db.Contest, db.Contest.contest_id == contest.contest_id)
+             .join(db.Contest)
+             .filter(db.Participant.year == ctx.round.year)
+             .filter(db.Participation.contest_id == db.Contest.contest_id))
+    if ctx.contest:
+        query = query.filter(db.Contest.contest_id == ctx.contest.contest_id)
+        if ctx.site:
+            query = query.filter(db.Participation.place_id == ctx.site.place_id)
     else:
-        query = query.filter(db.Contest.round == round)
+        query = query.filter(db.Contest.round == ctx.round)
+        if ctx.hier_place:
+            query = db.filter_place_nth_parent(query, db.Contest.place_id, ctx.round.level - ctx.hier_place.level, ctx.hier_place.place_id)
         query = query.options(joinedload(db.Contest.place))
-    query = query.filter(db.Participation.contest_id == db.Contest.contest_id)
-    if site:
-        query = query.filter(db.Participation.place_id == site.place_id)
     if contest_place:
         query = query.filter(db.Contest.place_id == contest_place.place_id)
     if participation_place:
-- 
GitLab