Skip to content
Snippets Groups Projects
Commit c5cd35ef authored by Martin Mareš's avatar Martin Mareš
Browse files

Diplomy/UI: Schvalování diplomů

parent 49eeb29f
No related branches found
No related tags found
No related merge requests found
......@@ -7,6 +7,7 @@ from markupsafe import Markup
import os
from sqlalchemy.orm import joinedload
from typing import Tuple, Optional, Dict
import werkzeug.exceptions
import wtforms
from wtforms import validators
......@@ -85,6 +86,12 @@ class CertSetForm(FlaskForm):
return ok
class CertApproveForm(FlaskForm):
ctype = wtforms.HiddenField()
approve = wtforms.SubmitField("Schválit")
unapprove = wtforms.SubmitField("Zrušit schválení")
@app.route('/org/contest/c/<int:ct_id>/certificates', methods=('GET', 'POST'))
def org_certificates(ct_id: int):
ctx = get_context(ct_id=ct_id, right_needed=Right.view_contestants)
......@@ -119,10 +126,30 @@ def org_certificates(ct_id: int):
del form.tex_hacks
if new_cset:
del form.delete
approve_form = CertApproveForm()
else:
form = None
approve_form = None
if approve_form and approve_form.validate_on_submit():
try:
ctype = db.CertType.coerce(approve_form.ctype.data)
except ValueError:
raise werkzeug.exceptions.UnprocessableEntity()
cfile = sess.query(db.CertFile).filter_by(cert_set_id=ct_id, type=ctype).one_or_none()
if cfile:
if approve_form.approve.data:
cfile.approved = True
flash(f'Diplomy ({ctype.friendly_name()}) schváleny.', 'success')
elif approve_form.unapprove.data:
cfile.approved = False
flash(f'Odvoláno schválení diplomů ({ctype.friendly_name()}).', 'success')
sess.commit()
return redirect(ctx.url_for('org_certificates'))
else:
flash('Tento typ diplomů nebyl vytvořen.', 'danger')
if form:
elif form:
if not form.is_submitted():
pass
elif not form.validate() or not form.osmo_validate(cset):
......@@ -201,6 +228,7 @@ def org_certificates(ct_id: int):
cert_files_by_type: Dict[db.CertType, Optional[db.CertFile]] = {}
for cf in sess.query(db.CertFile).filter_by(cert_set_id=ct_id).all():
cert_files_by_type[cf.type] = cf
cert_file_columns = [(t, cert_files_by_type.get(t)) for t in db.CertType]
certs_by_uid_type: Dict[Tuple[int, db.CertType], db.Certificate] = {}
for c in sess.query(db.Certificate).filter_by(cert_set_id=ct_id).all():
......@@ -211,9 +239,10 @@ def org_certificates(ct_id: int):
ctx=ctx,
group_rounds=group_rounds,
form=form,
approve_form=approve_form,
cset=cset,
users_pions=users_pions,
cert_files_by_type=cert_files_by_type,
cert_file_columns=cert_file_columns,
certs_by_uid_type=certs_by_uid_type,
settings_changed=(cset.changed_at is not None and (cset.certs_issued_at is None or cset.certs_issued_at < cset.changed_at)),
scoretable_changed=(cset.scoretable != contest.scoretable),
......
......@@ -31,8 +31,12 @@
Zde je možné vytvořit účastnické listy pro všechny soutěžící,
po vytvoření oficiální výsledkové listiny také diplomy vítězů / úspěšných řešitelů
a pochvalná uznání (pokud se v tomto kole vydávají).
</p>
<p>
Hotové diplomy si můžete stáhnout a vytisknout.
Po uzavření kola budou také dostupné soutěžícím v OSMO.
Pokud je schválíte, po uzavření kola budou dostupné soutěžícím a jejich
školním garantům v OSMO.
</p>
<h3>Diplomy</h3>
......@@ -53,8 +57,15 @@ Po uzavření kola budou také dostupné soutěžícím v OSMO.
<thead>
<tr>
<th>Jméno
{% for t in CertType %}
<th class=ac>{{ t.friendly_name()|titlecase }}
{% for t, cfile in cert_file_columns %}
<th class=ac>{{ t.friendly_name()|titlecase }}<br>
{% if cfile %}
{% if cfile.approved %}
<em>(schváleno)</em>
{% else %}
<em>(neschváleno)</em>
{% endif %}
{% endif %}
{% endfor %}
<tbody>
{% for user, pion in users_pions %}
......@@ -63,7 +74,7 @@ Po uzavření kola budou také dostupné soutěžícím v OSMO.
{% if pion.state != PartState.active %}
({{ pion.state.friendly_name() }})
{% endif %}
{% for t in CertType %}
{% for t, cfile in cert_file_columns %}
{% set cert = certs_by_uid_type[user.user_id, t] %}
{% if cert %}
<td class=ac><a href="{{ ctx.url_for('org_cert_file', cert_type=t.name, user_id=user.user_id, filename=t.file_name(False) + '.pdf') }}">{{ cert.achievement }}</a>
......@@ -75,14 +86,31 @@ Po uzavření kola budou také dostupné soutěžícím v OSMO.
<tfoot>
<tr>
<th>Všichni dohromady
{% for t in CertType %}
{% set cfile = cert_files_by_type[t] %}
{% for t, cfile in cert_file_columns %}
{% if cfile %}
<th class=ac><a href="{{ ctx.url_for('org_cert_file', cert_type=t.name, filename=t.file_name(True) + '.pdf') }}">stáhnout</a>
{% else %}
<th>
{% endif %}
{% endfor %}
{% if approve_form %}
<tr>
<th>Akce
{% for t, cfile in cert_file_columns %}
<td class=ac>
{% if cfile %}
<form method="POST" action="">
{{ approve_form.csrf_token }}
<input type="hidden" name="ctype" value="{{t.name}}">
{% if cfile.approved %}
{{ approve_form.unapprove(class='btn btn-xs btn-danger') }}
{% else %}
{{ approve_form.approve(class='btn btn-xs btn-success') }}
{% endif %}
</form>
{% endif %}
{% endfor %}
{% endif %}
</table>
{% if settings_changed or scoretable_changed %}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment