From bb2a29d219d0112baa503ceff3bc072ad68bad18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pracha=C5=99?= <jan.prachar@gmail.com>
Date: Fri, 12 Mar 2021 01:38:33 +0100
Subject: [PATCH] =?UTF-8?q?Desetinn=C3=A9=20body:=20Limity=20na=20v=C3=ADt?=
 =?UTF-8?q?=C4=9Bze=20a=20=C3=BAsp=C4=9B=C5=A1n=C3=A9=20=C5=99e=C5=A1itele?=
 =?UTF-8?q?=20jsou=20tak=C3=A9=20desetinn=C3=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Issue #189
---
 db/upgrade-20210328.sql         |  4 +++-
 mo/db.py                        |  4 ++--
 mo/web/jinja.py                 |  1 +
 mo/web/org_round.py             | 10 +++++-----
 mo/web/templates/org_round.html |  4 ++--
 mo/web/templates/org_score.html |  4 ++--
 6 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/db/upgrade-20210328.sql b/db/upgrade-20210328.sql
index f237e0c8..5d2b29cb 100644
--- a/db/upgrade-20210328.sql
+++ b/db/upgrade-20210328.sql
@@ -1,7 +1,9 @@
 SET ROLE 'mo_osmo';
 
 ALTER TABLE rounds
-        ADD COLUMN points_step	numeric(2,1)	NOT NULL DEFAULT 1;		-- s jakou přesností jsou přidělovány body (celé aneb 1, 0.5, 0.1)
+        ADD COLUMN points_step	numeric(2,1)	NOT NULL DEFAULT 1,		-- s jakou přesností jsou přidělovány body (celé aneb 1, 0.5, 0.1)
+        ALTER COLUMN score_winner_limit SET DATA TYPE numeric(5,1),
+        ALTER COLUMN score_successful_limit SET DATA TYPE numeric(5,1);
 
 ALTER TABLE solutions
         ALTER COLUMN points SET DATA TYPE numeric(5,1);
diff --git a/mo/db.py b/mo/db.py
index cbf22056..141fb727 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -218,8 +218,8 @@ class Round(Base):
     pr_tasks_start = Column(DateTime(True))
     pr_submit_end = Column(DateTime(True))
     score_mode = Column(Enum(RoundScoreMode, name='score_mode'), nullable=False, server_default=text("'basic'::score_mode"))
-    score_winner_limit = Column(Integer)
-    score_successful_limit = Column(Integer)
+    score_winner_limit = Column(Numeric)
+    score_successful_limit = Column(Numeric)
     points_step = Column(Numeric, nullable=False)
     has_messages = Column(Boolean, nullable=False, server_default=text("false"))
 
diff --git a/mo/web/jinja.py b/mo/web/jinja.py
index e6721b20..9ccf3e5e 100644
--- a/mo/web/jinja.py
+++ b/mo/web/jinja.py
@@ -24,6 +24,7 @@ app.jinja_env.trim_blocks = True
 
 app.jinja_env.filters.update(timeformat=util_format.timeformat)
 app.jinja_env.filters.update(inflected=util_format.inflect_number)
+app.jinja_env.filters.update(inflected_by=util_format.inflect_by_number)
 app.jinja_env.filters.update(timedelta=util_format.timedelta)
 app.jinja_env.filters.update(time_and_timedelta=util_format.time_and_timedelta)
 app.jinja_env.filters.update(data_size=util_format.data_size)
diff --git a/mo/web/org_round.py b/mo/web/org_round.py
index 1db5b939..8d8b16ff 100644
--- a/mo/web/org_round.py
+++ b/mo/web/org_round.py
@@ -12,7 +12,6 @@ from typing import Optional, Tuple
 import werkzeug.exceptions
 import wtforms
 from wtforms import validators, ValidationError
-from wtforms.fields.html5 import DecimalField, IntegerField
 from wtforms.widgets.html5 import NumberInput
 
 import mo
@@ -21,6 +20,7 @@ import mo.imports
 from mo.rights import Right, RoundRights
 import mo.util
 from mo.web import app
+from mo.web.util import MODecimalField
 from mo.web.org_contest import ParticipantsActionForm, ParticipantsFilterForm, get_contestant_emails, get_contestants_query, make_contestant_table, \
     generic_import, generic_batch_download, generic_batch_upload, generic_batch_points
 
@@ -429,12 +429,12 @@ class RoundEditForm(FlaskForm):
     ct_submit_end = MODateTimeField("Konec odevzdávání pro účastníky", validators=[validators.Optional()])
     pr_submit_end = MODateTimeField("Konec odevzdávání pro dozor", validators=[validators.Optional()])
     score_mode = wtforms.SelectField("Výsledková listina", choices=db.RoundScoreMode.choices(), coerce=db.RoundScoreMode.coerce)
-    score_winner_limit = IntegerField(
-        "Hranice bodů pro vítěze", validators=[validators.Optional()],
+    score_winner_limit = MODecimalField(
+        "Hranice bodů pro vítěze", validators=[validators.Optional(), validators.NumberRange(min=0)],
         description="Řešitelé s alespoň tolika body budou označeni za vítěze, prázdná hodnota = žádné neoznačovat",
     )
-    score_successful_limit = IntegerField(
-        "Hranice bodů pro úspěšné řešitele", validators=[validators.Optional()],
+    score_successful_limit = MODecimalField(
+        "Hranice bodů pro úspěšné řešitele", validators=[validators.Optional(), validators.NumberRange(min=0)],
         description="Řešitelé s alespoň tolika body budou označeni za úspěšné řešitele, prázdná hodnota = žádné neoznačovat",
     )
     points_step = wtforms.SelectField(
diff --git a/mo/web/templates/org_round.html b/mo/web/templates/org_round.html
index 5a568a65..87c14a11 100644
--- a/mo/web/templates/org_round.html
+++ b/mo/web/templates/org_round.html
@@ -59,8 +59,8 @@
 		{% endif %}
 	</thead>
 	<tr><td>Výsledková listina<td>{{ round.master.score_mode.friendly_name() }}
-	<tr><td>Hranice bodů pro vítěze<td>{{ round.master.score_winner_limit|none_value(Markup('<i>nenastaveno</i>')) }}
-	<tr><td>Hranice bodů pro úspěšné řešitele<td>{{ round.master.score_successful_limit|none_value(Markup('<i>nenastaveno</i>')) }}
+	<tr><td>Hranice bodů pro vítěze<td>{{ round.master.score_winner_limit|decimal|none_value(Markup('<i>nenastaveno</i>')) }}
+	<tr><td>Hranice bodů pro úspěšné řešitele<td>{{ round.master.score_successful_limit|decimal|none_value(Markup('<i>nenastaveno</i>')) }}
 	<tr><td>Přesnost bodování<td>{{ round.points_step_name() }}
 </table>
 <div style="clear: both;"></div>
diff --git a/mo/web/templates/org_score.html b/mo/web/templates/org_score.html
index 21740346..8220ad36 100644
--- a/mo/web/templates/org_score.html
+++ b/mo/web/templates/org_score.html
@@ -55,10 +55,10 @@ Rozkliknutím bodů se lze dostat na detail daného řešení.</p>
 {% if master.score_winner_limit is not none or master.score_successful_limit is not none %}
 <p>
 {% if master.score_winner_limit is not none %}
-<b>Vítězi</b> se stávají účastníci s alespoň <b>{{ master.score_winner_limit|inflected("bodem", "body", "body") }}</b>.
+<b>Vítězi</b> se stávají účastníci s alespoň <b>{{ master.score_winner_limit|decimal }} {{ master.score_winner_limit|inflected_by("bodem", "body", "body") }}</b>.
 {% endif %}
 {% if master.score_successful_limit is not none %}
-<b>Úspěšnými řešiteli</b> se stávají účastníci s alespoň <b>{{ master.score_successful_limit|inflected("bodem", "body", "body") }}</b>.
+<b>Úspěšnými řešiteli</b> se stávají účastníci s alespoň <b>{{ master.score_successful_limit|decimal }} {{ master.score_successful_limit|inflected_by("bodem", "body", "body") }}</b>.
 {% endif %}
 {% endif %}
 
-- 
GitLab