Fix anonymous ordering and dish change

This commit is contained in:
Midgard 2020-02-26 21:25:51 +01:00
parent e15b085006
commit 729dab2ba4
Signed by: midgard
GPG key ID: 511C112F1331BBB4
3 changed files with 50 additions and 38 deletions

View file

@ -3,7 +3,7 @@ from datetime import datetime, timedelta
from typing import Optional
from flask import session
from flask import session, request
from flask_login import current_user
from flask_wtf import FlaskForm as Form
from wtforms import (DateTimeField, SelectField, SelectMultipleField, StringField, SubmitField,
@ -65,6 +65,8 @@ class OrderItemForm(Form):
(dish.id, (dish.name + ": " + self.format_price_range(dish.price_range())))
for dish in location.dishes
]
if not self.is_submitted() and self.comment.data is None:
self.comment.data = request.args.get("comment")
class AnonOrderItemForm(OrderItemForm):
@ -72,7 +74,7 @@ class AnonOrderItemForm(OrderItemForm):
Class which defines the form for a new Item in an Order
For Users who aren't logged in
"""
name = StringField("Name", validators=[validators.required()])
user_name = StringField("Name", validators=[validators.required()])
def populate(self, location: Location) -> None:
"""
@ -80,8 +82,11 @@ class AnonOrderItemForm(OrderItemForm):
the name of the anon user
"""
OrderItemForm.populate(self, location)
if self.name.data is None:
self.name.data = session.get("anon_name", None)
if not self.is_submitted():
if self.user_name.data is None:
self.user_name.data = request.args.get("user_name")
if self.user_name.data is None:
self.user_name.data = session.get("anon_name", None)
def validate(self) -> bool:
"Check if the provided anon_name is not already taken"
@ -90,8 +95,8 @@ class AnonOrderItemForm(OrderItemForm):
return False
# check if we have a user with this name
user = User.query.filter_by(username=self.name.data).first()
user = User.query.filter_by(username=self.user_name.data).first()
if user is not None:
self.name.errors.append("Name already in use")
self.user_name.errors.append("Name already in use")
return False
return True

View file

@ -42,9 +42,6 @@
{% if form -%}
<div class="col-md-push-1 col-md-10 darker order_order" id="form">
<h4>Order:</h4>
{% if current_user.is_anonymous() %}
<div>Sorry, anonymous ordering is currently broken. Please log in to order.</div>
{% else %}
<form method="post" action="{{ url_for('order_bp.order_item_create', order_id=order.id) }}">
<span class="pull-right">
<a class="btn btn-primary" onclick="chooseRandom()">Choose for me</a>
@ -83,10 +80,10 @@
</div>
{% if current_user.is_anonymous() %}
<div class="form-group{{ ' has-error' if form.name.errors }}{{ ' required' if form.name.flags.required }}">
{{ form.name.label(class='control-label') }}
{{ form.name(class='form-control', placeholder='Fill in your name...') }}
{{ util.render_form_field_errors(form.name) }}
<div class="form-group{{ ' has-error' if form.user_name.errors }}{{ ' required' if form.user_name.flags.required }}">
{{ form.user_name.label(class='control-label') }}
{{ form.user_name(class='form-control', placeholder='Fill in your name...') }}
{{ util.render_form_field_errors(form.user_name) }}
</div>
{% endif %}
<div class="form-group" style="padding-top: 8px;">
@ -96,7 +93,6 @@
{% endif %}
</div>
</form>
{% endif %}
</div>
{%- endif %}
</div>

View file

@ -129,32 +129,40 @@ def order_item_create(order_id: int) -> typing.Any:
dish_id = form.dish_id.data if form.is_submitted() else request.args.get("dish")
if dish_id and not location.dish_by_id(dish_id):
abort(404)
form.dish_id.data = dish_id
if not form.is_submitted():
form.dish_id.data = dish_id
form.populate(current_order.location)
# If the form was not submitted (GET request), the form had errors,
# or the dish was changed: show form again
dish_was_changed = request.form.get("form_for_dish_id") and request.form["form_for_dish_id"] != dish_id
if not form.validate_on_submit() or dish_was_changed:
if form.is_submitted():
form_for_dish = request.form.get("form_for_dish_id")
dish_was_changed = form_for_dish is not None and form_for_dish != dish_id
# The form's validation tests that dish_id is valid and gives a friendly error if it's not
choices = location.dish_by_id(form.dish_id.data).choices
chosen = [
(
choice.option_by_id(request.form.get("choice_" + choice.id))
if choice_type == "single_choice" else
list(ignore_none(request.form.getlist("choice_" + choice.id, type=choice.option_by_id)))
)
for (choice_type, choice) in choices
]
all_choices_present = all(x is not None for x in chosen)
if dish_was_changed or not all_choices_present:
user_name = form.user_name.data if form.user_name.validate(form) else None
comment = form.comment.data if form.comment.validate(form) else None
return redirect(url_for("order_bp.order_item_create",
order_id=order_id, dish=form.dish_id.data,
user_name=user_name, comment=comment))
# If the form was not submitted (GET request) or the form had errors: show form again
if not form.validate_on_submit():
return order_from_id(order_id, form=form, dish_id=dish_id)
# Form was submitted and is valid
# The form's validation tests that dish_id is valid and gives a friendly error if it's not
choices = location.dish_by_id(form.dish_id.data).choices
chosen = [
(
choice.option_by_id(request.form.get("choice_" + choice.id))
if choice_type == "single_choice" else
list(ignore_none(request.form.getlist("choice_" + choice.id, type=choice.option_by_id)))
)
for (choice_type, choice) in choices
]
all_choices_present = all(x is not None for x in chosen)
if not all_choices_present:
return redirect(url_for("order_bp.order_item_create",
order_id=order_id, dish=form.dish_id.data))
item = OrderItem()
form.populate_obj(item)
item.hlds_data_version = location_definition_version
@ -162,15 +170,18 @@ def order_item_create(order_id: int) -> typing.Any:
if not current_user.is_anonymous():
item.user_id = current_user.id
else:
session["anon_name"] = item.name
session["anon_name"] = item.user_name
# XXX Temporary until OrderItemChoice is used
def _name(option):
no_text_tag = "no_text"
try:
if not option or no_text_tag in option.tags:
return None
return option.name
except AttributeError:
return ", ".join(o.name for o in option)
comments = [_name(option) for option in chosen if option and "no_text" not in option.tags]
return ", ".join(o.name for o in option if no_text_tag not in o.tags)
comments = list(ignore_none(_name(option) for option in chosen))
if item.comment:
comments.append("Comment: " + item.comment)
item.comment = "; ".join(comments)
@ -221,7 +232,7 @@ def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]:
).all()
else:
items = OrderItem.query.filter(
(OrderItem.name == user_name) & (OrderItem.order_id == order_id)
(OrderItem.user_name == user_name) & (OrderItem.order_id == order_id)
).all()
current_order = Order.query.filter(Order.id == order_id).first()
for item in items: