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

Přesuny míst

Dvojkrokově, nejdříve vyhledání a pak přesun. Lze přesunout jen pod místa,
která neporuší constrain na level daného typu a která mohu editovat.
parent de50dd29
No related branches found
No related tags found
1 merge request!4Dodělávky manipulace s places
This commit is part of merge request !4. Comments created here will be created in the context of that merge request.
...@@ -101,6 +101,16 @@ class Place(Base): ...@@ -101,6 +101,16 @@ class Place(Base):
return len(PlaceType.choices(level=self.level + 1)) > 0 return len(PlaceType.choices(level=self.level + 1)) > 0
def place_by_code(code: str) -> Optional[Place]:
if code.startswith("#"):
try:
id = int(code[1:])
return get_session().query(Place).get(id)
except ValueError:
return None
return get_session().query(Place).filter_by(code=code).first()
class School(Base): class School(Base):
__tablename__ = 'schools' __tablename__ = 'schools'
......
...@@ -157,6 +157,82 @@ def org_place_edit(id: int): ...@@ -157,6 +157,82 @@ def org_place_edit(id: int):
) )
class PlaceMoveForm(FlaskForm):
code = wtforms.StringField(validators=[validators.DataRequired()])
submit = wtforms.SubmitField('Najít místo')
reset = wtforms.HiddenField()
move = wtforms.HiddenField()
class PlaceMoveConfirmForm(FlaskForm):
code = wtforms.HiddenField()
reset = wtforms.SubmitField('Zrušit')
move = wtforms.SubmitField('Přesunout')
@app.route('/org/place/<int:id>/move', methods=('GET', 'POST'))
def org_place_move(id: int):
sess = db.get_session()
# Tests: can move only existing places that we can edit
place = sess.query(db.Place).get(id)
if not place:
raise werkzeug.exceptions.NotFound()
rr = mo.rights.Rights(g.user)
rr.get_for(place)
if not rr.can_edit_place(place):
raise werkzeug.exceptions.Forbidden()
parents = reversed(db.get_place_parents(place)[1:]) # without place itself and from the top
new_parents = None
search_error = None
form = PlaceMoveForm()
form_confirm = None
if form.validate_on_submit():
if form.reset.data:
return redirect(url_for('org_place_move', id=id))
new_parent = db.place_by_code(form.code.data)
if not new_parent:
search_error = 'Místo s tímto kódem se nepovedlo nalézt'
else:
new_parents = reversed(db.get_place_parents(new_parent))
(_, levels) = db.place_type_names_and_levels[place.type]
rr.get_for(new_parent)
if not rr.can_edit_place(new_parent):
search_error = 'Nemáte právo k editaci vybraného nadřazeného místa, přesun nelze uskutečnit'
elif (new_parent.level + 1) not in levels:
search_error = f'Toto místo ({place.type_name()}) nelze přemístit pod vybrané místo ({new_parent.type_name()}), dostalo by se na nepovolený level'
elif new_parent.place_id == place.parent:
search_error = 'Žádná změna, místo je zde již umístěno'
elif form.move.data:
# Everything is OK, if submitted with 'move' do the move
place.parent = new_parent.place_id
place.level = new_parent.level + 1
changes = db.get_object_changes(place)
mo.util.log(
type=db.LogType.place,
what=id,
details={'action': 'move', 'changes': changes},
)
app.logger.info(f"Place {id} moved, changes: {changes}")
db.get_session().commit()
flash('Místo úspěšně přesunuto', 'success')
return redirect(url_for('org_place', id=id))
else:
# OK but not confirmed yet, display the confirm form
form_confirm = PlaceMoveConfirmForm()
form_confirm.code.data = form.code.data
return render_template(
'org_place_move.html',
place=place, form=form, form_confirm=form_confirm, search_error=search_error,
parents=parents, new_parents=new_parents
)
@app.route('/org/place/<int:id>/delete', methods=('POST',)) @app.route('/org/place/<int:id>/delete', methods=('POST',))
def org_place_delete(id: int): def org_place_delete(id: int):
sess = db.get_session() sess = db.get_session()
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
{% if can_edit %} {% if can_edit %}
<div class="btn-group" role="group" style="margin: 10px 0px;"> <div class="btn-group" role="group" style="margin: 10px 0px;">
<a class="btn btn-primary" href="{{ url_for('org_place_edit', id=place.place_id) }}">Editovat</a> <a class="btn btn-primary" href="{{ url_for('org_place_edit', id=place.place_id) }}">Editovat</a>
<a class="btn btn-primary" href="{{ url_for('org_place_move', id=place.place_id) }}">Přesunout</a>
<form class="btn-group" method="POST" onsubmit="return confirm('Opravdu nenávratně smazat?')" action='{{ url_for('org_place_delete', id=place.place_id) }}'> <form class="btn-group" method="POST" onsubmit="return confirm('Opravdu nenávratně smazat?')" action='{{ url_for('org_place_delete', id=place.place_id) }}'>
<input class="btn btn-danger" type=submit value='Smazat'> <input class="btn btn-danger" type=submit value='Smazat'>
</form> </form>
......
...@@ -11,16 +11,4 @@ ...@@ -11,16 +11,4 @@
{{ wtf.quick_form(form, form_type='horizontal') }} {{ wtf.quick_form(form, form_type='horizontal') }}
<hr>
<h3>Přesun místa</h3>
<p><b>Nadřazená místa:</b>
{% for parent in parents %}
<a href='{{ url_for('org_place', id=parent.place_id) }}'>{{ parent.name }}</a> &rightarrow;
{% endfor %}
<i>{{ place.name }}</i></p>
<p>TODO: přesun pod jiné místo</p>
{% endblock %} {% endblock %}
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block body %}
<h2>{{ place.type_name().title() }}: {{ place.name }}</h2>
<a href='{{ url_for('org_place', id=place.place_id) }}'>Zpět na detail místa</a>
<hr>
<h3>Přesun místa</h3>
<p><b>Současné nadřazené místo:</b>
{% for parent in parents %}
{% if loop.index != 1 %}&rightarrow;{% endif %}<a href='{{ url_for('org_place', id=parent.place_id) }}'>{{ parent.name }}</a>
{% endfor %}
</p>
<h4>Krok 1: Vyhledání místa</h4>
<p>Vyhledejte místo podle jeho kódu. Můžete zadat i ID ve formátu <code>#123</code>.</p>
{{ wtf.quick_form(form, form_type='inline') }}
{% if new_parents %}
<p><b>Vyhledané nadřazené místo:</b>
{% for parent in new_parents %}
{% if loop.index != 1 %}&rightarrow;{% endif %} <a href='{{ url_for('org_place', id=parent.place_id) }}'>{{ parent.name }}</a>
{% endfor %}
</p>
{% endif %}
{% if search_error %}
<div class="alert alert-danger" role="alert">
{{ search_error }}
</div>
{% endif %}
{% if form_confirm %}
<h4>Krok 2: Potvrdit přesun</h4>
{{ wtf.quick_form(form_confirm, form_type='inline') }}
{% endif %}
{% endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment