Skip to content
Snippets Groups Projects
Commit 0cc470b8 authored by Jiří Setnička's avatar Jiří Setnička
Browse files

Přidání, editace a mazání úloh

Smazat lze jen úlohu, na kterou není nic navázané
parent 2345c941
No related branches found
No related tags found
2 merge requests!10Nastavení kol a úloh,!9WIP: Zárodek uživatelské části webu a submitování
...@@ -47,11 +47,19 @@ def org_rounds(): ...@@ -47,11 +47,19 @@ def org_rounds():
return render_template('org_rounds.html', rounds=rounds, level_names=mo.db.place_level_names) return render_template('org_rounds.html', rounds=rounds, level_names=mo.db.place_level_names)
@app.route('/org/contest/r/<int:id>/') class TaskDeleteForm(FlaskForm):
delete_task_id = wtforms.IntegerField()
delete = wtforms.SubmitField('Smazat úlohu')
@app.route('/org/contest/r/<int:id>/', methods=('GET', 'POST'))
def org_round(id: int): def org_round(id: int):
sess = db.get_session() sess = db.get_session()
round, rr = get_round_rr(id, None) round, rr = get_round_rr(id, None)
can_manage_round = rr.have_right(mo.rights.Right.manage_round)
can_manage_contestants = rr.have_right(mo.rights.Right.manage_contest)
contests = (sess.query(db.Contest) contests = (sess.query(db.Contest)
.filter_by(round=round) .filter_by(round=round)
.options(joinedload(db.Contest.place)) .options(joinedload(db.Contest.place))
...@@ -59,13 +67,119 @@ def org_round(id: int): ...@@ -59,13 +67,119 @@ def org_round(id: int):
contests.sort(key=lambda c: locale.strxfrm(c.place.name)) contests.sort(key=lambda c: locale.strxfrm(c.place.name))
tasks = sess.query(db.Task).filter_by(round=round).all()
tasks.sort(key=lambda t: t.code)
form_delete_task = TaskDeleteForm()
if can_manage_contestants and form_delete_task.validate_on_submit():
delete_task = sess.query(db.Task).filter_by(
round_id=id, task_id=form_delete_task.delete_task_id.data
).first()
if not delete_task:
flash('Úloha s daným ID v tomto kole neexistuje', 'danger')
elif sess.query(db.Solution).filter_by(task_id=delete_task.task_id).first() is not None:
flash(f'Úlohu {delete_task.code} nelze smazat, existují řešení vázající se na ní', 'danger')
elif sess.query(db.Paper).filter_by(for_task=delete_task.task_id).first() is not None:
flash(f'Úlohu {delete_task.code} nelze smazat, existují papíry vázající se na ní', 'danger')
elif sess.query(db.PointsHistory).filter_by(task_id=delete_task.task_id).first() is not None:
flash(f'Úlohu {delete_task.code} nelze smazat, existují přidělené body vázající se na ní', 'danger')
else:
sess.delete(delete_task)
mo.util.log(
type=db.LogType.task,
what=delete_task.task_id,
details={'action': 'delete', 'task': db.row2dict(delete_task)},
)
app.logger.info(f"Úloha {delete_task.code} ({delete_task.task_id}) smazána: {db.row2dict(delete_task)}")
sess.commit()
flash(f'Úloha {delete_task.code} úspěšně smazána', 'success')
return redirect(url_for('org_round', id=id))
return render_template( return render_template(
'org_round.html', 'org_round.html',
round=round, round=round,
contests=contests, contests=contests,
tasks=tasks, form_delete_task=form_delete_task,
level_names=mo.db.place_level_names, level_names=mo.db.place_level_names,
can_manage_round=rr.have_right(mo.rights.Right.manage_round), can_manage_round=can_manage_round,
can_manage_contestants=rr.have_right(mo.rights.Right.manage_contest), can_manage_contestants=can_manage_contestants,
)
class TaskEditForm(FlaskForm):
code = wtforms.StringField('Kód úlohy')
name = wtforms.StringField('Název úlohy')
submit = wtforms.SubmitField('Uložit')
@app.route('/org/contest/r/<int:id>/task/new', methods=('GET', 'POST'))
def org_round_task_new(id: int):
sess = db.get_session()
round, rr = get_round_rr(id, mo.rights.Right.manage_round)
form = TaskEditForm()
if form.validate_on_submit():
task = db.Task()
task.round = round
form.populate_obj(task)
if sess.query(db.Task).filter_by(round_id=id, code=task.code).first():
flash('Úloha se stejným kódem již v tomto kole existuje', 'danger')
else:
sess.add(task)
sess.flush()
mo.util.log(
type=db.LogType.task,
what=task.task_id,
details={'action': 'add', 'task': db.row2dict(task)},
)
sess.commit()
app.logger.info(f"Úloha {task.code} ({task.task_id}) přidána: {db.row2dict(task)}")
flash('Nová úloha přidána', 'success')
return redirect(url_for('org_round', id=id))
return render_template(
'org_round_task_edit.html',
round=round, task=None, form=form,
)
@app.route('/org/contest/r/<int:id>/task/<int:task_id>/edit', methods=('GET', 'POST'))
def org_round_task_edit(id: int, task_id: int):
sess = db.get_session()
round, rr = get_round_rr(id, mo.rights.Right.manage_round)
task = sess.query(db.Task).get(task_id)
if not task:
raise werkzeug.exceptions.NotFound()
form = TaskEditForm(obj=task)
if form.validate_on_submit():
if sess.query(db.Task).filter(
db.Task.task_id != task_id, db.Task.round_id == id, db.Task.code == form.code.data
).first():
flash('Úloha se stejným kódem již v tomto kole existuje', 'danger')
else:
form.populate_obj(task)
if sess.is_modified(task):
changes = db.get_object_changes(task)
mo.util.log(
type=db.LogType.task,
what=task_id,
details={'action': 'edit', 'changes': changes},
)
sess.commit()
app.logger.info(f"Úloha {task.code} ({task_id}) modifikována, změny: {changes}")
flash('Změny úlohy uloženy', 'success')
else:
flash(u'Žádné změny k uložení', 'info')
return redirect(url_for('org_round', id=id))
return render_template(
'org_round_task_edit.html',
round=round, task=task, form=form,
) )
......
...@@ -38,4 +38,36 @@ ...@@ -38,4 +38,36 @@
<p>Zatím nebyly založeny v žádné oblasti. <p>Zatím nebyly založeny v žádné oblasti.
{% endif %} {% endif %}
<h3>Úlohy</h3>
{% if can_manage_round %}
<a class="btn btn-primary right-float" href="{{ url_for('org_round_task_new', id=round.round_id) }}">Nová úloha</a>
{% endif %}
{% if tasks %}
<table class=data>
<thead>
<tr>
<th>Kód</th>
<th>Název</th>
{% if can_manage_round %}<th>Akce</th>{% endif %}
</tr>
</thead>
{% for task in tasks %}
<tr>
<td>{{ task.code }}</td>
<td>{{ task.name }}</td>
{% if can_manage_round %}<td>
<form action="" method="POST" onsubmit="return confirm('Opravdu nenávratně smazat?')" class="btn-group">
{{ form_delete_task.csrf_token() }}
<input type="hidden" name="delete_task_id" value="{{ task.task_id }}">
<a class="btn btn-xs btn-primary" href="{{ url_for('org_round_task_edit', id=round.round_id, task_id=task.task_id) }}">Editovat</a>
<button type="submit" class="btn btn-xs btn-danger">Smazat</button>
</form>
</td>{% endif %}
</tr>
{% endfor %}
</table>
{% else %}
<p>Zatím nebyly přidány žádné úlohy.</p>
{% endif %}
{% endblock %} {% endblock %}
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block body %}
<h2>
<a href='{{ url_for('org_round', id=round.round_id) }}'>Kolo {{ round.round_code() }}</a>­­
» {% if task %} Úloha {{ task.code }}: {{ task.name }}{% else %}Nová úloha{% endif %}
</h2>
{{ wtf.quick_form(form, form_type='horizontal') }}
{% endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment