From fb476c74d9aaa1ee3f59e34c68f32466301bd442 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Tue, 16 Feb 2021 18:10:19 +0100
Subject: [PATCH] =?UTF-8?q?Postup:=20R=C5=AFzn=C3=A1=20drobn=C3=A1=20vylep?=
 =?UTF-8?q?=C5=A1en=C3=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Po commitu redirectujeme zpět
- Logujeme
- Počítáme, kolik účastí jsme opravdu vytvořili
  (byl trochu hlavolam zařídit to s INSERT ... ON CONFLICT IGNORE)
---
 mo/web/org_contest.py | 63 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 13 deletions(-)

diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 62392153..89474d8d 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -19,7 +19,7 @@ from mo.imports import ImportType, create_import
 import mo.jobs.submit
 from mo.rights import Right, Rights
 import mo.util
-from mo.util_format import inflect_number
+from mo.util_format import inflect_number, inflect_by_number
 from mo.web import app
 import mo.web.util
 from mo.web.util import PagerForm
@@ -1204,21 +1204,24 @@ def org_contest_advance(contest_id: int):
     conn = sess.connection()
     contest, rr = get_contest_rr(contest_id, Right.manage_contest)
 
+    def redirect_back():
+        return redirect(url_for('org_contest', id=contest_id))
+
     round = contest.round
     if round.state != db.RoundState.preparing:
         flash('Aktuální kolo není ve stavu přípravy', 'danger')
-        return redirect(url_for('org_contest', id=contest_id))
+        return redirect_back()
 
     prev_round = sess.query(db.Round).filter_by(year=round.year, category=round.category, seq=round.seq - 1).one_or_none()
     if prev_round is None:
         flash('Předchozí kolo nenalezeno', 'danger')
-        return redirect(url_for('org_contest', id=contest_id))
+        return redirect_back()
     elif prev_round.state != db.RoundState.closed:
         flash('Předchozí kolo dosud nebylo ukončeno', 'danger')
-        return redirect(url_for('org_contest', id=contest_id))
+        return redirect_back()
     elif prev_round.level < round.level:
         flash('Předchozí kolo se koná ve vyšší oblasti než toto kolo', 'danger')
-        return redirect(url_for('org_contest', id=contest_id))
+        return redirect_back()
 
     prev_contests: List[db.Contest] = []
     accept_by_place_id: Dict[int, int] = {}
@@ -1255,6 +1258,15 @@ def org_contest_advance(contest_id: int):
             accept_uids = None
 
         want_execute = form.execute.data
+        if want_execute:
+            app.logger.info(f'Postup: Z kola #{prev_round.round_id} do #{round.round_id}, soutěž #{contest_id}')
+            mo.util.log(
+                type=db.LogType.contest,
+                what=contest_id,
+                details={'action': 'advance'},
+            )
+
+        really_inserted = 0
         for pp in prev_pions:
             if accept_uids and pp.user_id not in accept_uids:
                 reject_by_place_id[pp.place_id] += 1
@@ -1263,17 +1275,42 @@ def org_contest_advance(contest_id: int):
 
             if want_execute:
                 # ORM neumí ON CONFLICT DO NOTHING, takže musíme o vrstvu níže
-                ins = pgsql_insert(db.Participation.__table__).values(
-                    user_id=pp.user_id,
-                    contest_id=contest.contest_id,
-                    place_id=contest.place.place_id,
-                    state=db.PartState.invited,
-                ).on_conflict_do_nothing()
-                conn.execute(ins)
+                res = conn.execute(
+                    pgsql_insert(db.Participation.__table__)
+                    .values(
+                        user_id=pp.user_id,
+                        contest_id=contest.contest_id,
+                        place_id=contest.place.place_id,
+                        state=db.PartState.invited,
+                    )
+                    .on_conflict_do_nothing()
+                    .returning(db.Participation.contest_id)
+                )
+                inserted = res.fetchall()
+                if inserted:
+                    # Opravdu došlo ke vložení
+                    really_inserted += 1
+                    app.logger.info(f'Postup: Založena účast user=#{pp.user_id} contest=#{contest_id} place=#{contest.place_id}')
+                    mo.util.log(
+                        type=db.LogType.participant,
+                        what=pp.user_id,
+                        details={
+                            'action': 'add-to-contest',
+                            # Tady nemůžeme použít obvyklé row2dict, neboť nemáme v ruce ORMový objekt
+                            'new': {
+                                'contest_id': contest.contest_id,
+                                'place_id': contest.place_id,
+                            },
+                        },
+                    )
 
         if want_execute:
             sess.commit()
-            flash('Provedeno.', 'success')
+            msg = (inflect_by_number(really_inserted, 'Pozván', 'Pozváni', 'Pozváno')
+                   + ' '
+                   + inflect_number(really_inserted, 'nový soutěžící', 'noví soutěžící', 'nových soutěžících'))
+            flash(msg, 'success')
+            return redirect_back()
 
     return render_template(
         'org_contest_advance.html',
-- 
GitLab