From 2a42923812285729a1030a150b36f1ac1dbfc672 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Mon, 12 Jul 2021 15:20:33 +0200
Subject: [PATCH] =?UTF-8?q?Registrace:=20Zm=C4=9Bny=20v=20DB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- round: přibyly sloupec enroll_mode a enroll_advert
- participant: přibyl sloupec registered_on
- part_state: přidán stav "active", zrušeny "invited" a "present"
---
 db/db.ddl               | 20 +++++++++++++++-----
 db/upgrade-20210712.sql | 16 ++++++++++++++++
 mo/db.py                | 25 +++++++++++++++++++++----
 3 files changed, 52 insertions(+), 9 deletions(-)
 create mode 100644 db/upgrade-20210712.sql

diff --git a/db/db.ddl b/db/db.ddl
index fd3ce6c2..b0808cd7 100644
--- a/db/db.ddl
+++ b/db/db.ddl
@@ -89,6 +89,12 @@ CREATE TYPE score_mode AS ENUM (
 	'mo'				-- jednoznačné pořadí podle pravidel MO
 );
 
+CREATE TYPE enroll_mode AS ENUM (	-- režim přihlašování účastníků
+	'manual',			-- přihlašuje organizátor
+	'register',			-- účastník se registruje
+	'confirm'			-- účastník se registruje, ale org ho musí potvrdit
+);
+
 CREATE TABLE rounds (
 	round_id	serial		PRIMARY KEY,
 	master_round_id	int		DEFAULT NULL REFERENCES rounds(round_id),
@@ -109,6 +115,8 @@ CREATE TABLE rounds (
 	score_successful_limit	int	DEFAULT NULL,			-- bodový limit na označení za úspěšného řešitele
 	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)
 	has_messages	boolean		NOT NULL DEFAULT false,		-- má zprávičky
+	enroll_mode	enroll_mode	NOT NULL DEFAULT 'manual',	-- režim přihlašování (pro vyšší kola vždy 'manual')
+	enroll_advert	varchar(255)	NOT NULL DEFAULT '',		-- popis v přihlašovacím formuláři
 	UNIQUE (year, category, seq, part)
 );
 
@@ -133,17 +141,19 @@ CREATE TABLE participants (
 	school		int		NOT NULL REFERENCES places(place_id),
 	birth_year	int		NOT NULL,
 	grade		varchar(20)	NOT NULL,			-- třída ve tvaru "X/Y"
+	registered_on	timestamp with time zone	DEFAULT NULL,	-- kdy se účastník přihlásil (NULL, pokud ho přihlásil organizátor)
 	PRIMARY KEY (user_id, year)
 );
 
 -- Účast v soutěžním kole
 
 CREATE TYPE part_state AS ENUM (
-	'registered',		-- sám se přihlásil
-	'invited',		-- pozván
-	'refused',		-- odmítl účast
-	'present',		-- soutěžil
-	'absent',		-- bez omluvy nedorazil
+	'registered',		-- sám se přihlásil, čeká na potvrzení organizátorem
+	-- 'invited',		-- pozván (už nepoužíváme)
+	'active',		-- soutěží (přihlášku zadal/potvrdil organizátor)
+	'refused',		-- organizátor odmítl přihlášku
+	-- 'present',		-- soutěžil (už nepoužíváme)
+	'absent',		-- nedorazil
 	'disqualified'		-- diskvalifikovaný
 );
 
diff --git a/db/upgrade-20210712.sql b/db/upgrade-20210712.sql
new file mode 100644
index 00000000..737c4b66
--- /dev/null
+++ b/db/upgrade-20210712.sql
@@ -0,0 +1,16 @@
+SET ROLE 'mo_osmo';
+
+CREATE TYPE enroll_mode AS ENUM (	-- režim přihlašování účastníků
+	'manual',			-- přihlašuje organizátor
+	'register',			-- účastník se registruje
+	'confirm'			-- účastník se registruje, ale org ho musí potvrdit
+);
+
+ALTER TABLE rounds ADD COLUMN enroll_mode enroll_mode NOT NULL DEFAULT 'manual';
+ALTER TABLE rounds ADD COLUMN enroll_advert varchar(255) NOT NULL DEFAULT '';
+
+ALTER TYPE part_state ADD VALUE 'active' AFTER 'invited';
+
+ALTER TABLE participants ADD COLUMN registered_on timestamp with time zone DEFAULT NULL;
+
+UPDATE participations SET state='active' WHERE state IN ('registered', 'invited');
diff --git a/mo/db.py b/mo/db.py
index c1de5014..7ef56460 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -203,6 +203,22 @@ round_score_mode_names = {
 }
 
 
+class RoundEnrollMode(MOEnum):
+    manual = auto()
+    register = auto()
+    confirm = auto()
+
+    def friendly_name(self) -> str:
+        return round_enroll_mode_names[self]
+
+
+round_enroll_mode_names = {
+    RoundEnrollMode.manual: "Jen organizátoři",
+    RoundEnrollMode.register: "Účastníci sami",
+    RoundEnrollMode.confirm: "Potvrzení organizátorem",
+}
+
+
 # V DB jako numeric(2,1), používá se tak snadněji, než enum
 round_points_step_names = {
     decimal.Decimal('1'): "Celé body",
@@ -237,6 +253,8 @@ class Round(Base):
     score_successful_limit = Column(Numeric)
     points_step = Column(Numeric, nullable=False)
     has_messages = Column(Boolean, nullable=False, server_default=text("false"))
+    enroll_mode = Column(Enum(RoundEnrollMode, name='enroll_mode'), nullable=False, server_default=text("'basic'::enroll_mode"))
+    enroll_advert = Column(String(255), nullable=False, server_default=text("''::text"))
 
     master = relationship('Round', primaryjoin='Round.master_round_id == Round.round_id', remote_side='Round.round_id', post_update=True)
 
@@ -403,6 +421,7 @@ class Participant(Base):
     school = Column(Integer, ForeignKey('places.place_id'), nullable=False)
     birth_year = Column(Integer, nullable=False)
     grade = Column(String(20), nullable=False)
+    registered_on = Column(DateTime(True))
 
     user = relationship('User')
     school_place = relationship('Place', primaryjoin='Participant.school == Place.place_id')
@@ -410,9 +429,8 @@ class Participant(Base):
 
 class PartState(MOEnum):
     registered = auto()
-    invited = auto()
+    active = auto()
     refused = auto()
-    present = auto()
     absent = auto()
     disqualified = auto()
 
@@ -422,9 +440,8 @@ class PartState(MOEnum):
 
 part_state_names = {
     PartState.registered: 'přihlášený',
-    PartState.invited: 'pozvaný',
+    PartState.active: 'soutěží',
     PartState.refused: 'odmítnutý',
-    PartState.present: 'přítomný',
     PartState.absent: 'nepřítomný',
     PartState.disqualified: 'diskvalifikovaný',
 }
-- 
GitLab