Fix anonymous ordering and dish change
This commit is contained in:
parent
e15b085006
commit
729dab2ba4
3 changed files with 50 additions and 38 deletions
17
app/forms.py
17
app/forms.py
|
@ -3,7 +3,7 @@ from datetime import datetime, timedelta
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from flask import session
|
from flask import session, request
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from flask_wtf import FlaskForm as Form
|
from flask_wtf import FlaskForm as Form
|
||||||
from wtforms import (DateTimeField, SelectField, SelectMultipleField, StringField, SubmitField,
|
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())))
|
(dish.id, (dish.name + ": " + self.format_price_range(dish.price_range())))
|
||||||
for dish in location.dishes
|
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):
|
class AnonOrderItemForm(OrderItemForm):
|
||||||
|
@ -72,7 +74,7 @@ class AnonOrderItemForm(OrderItemForm):
|
||||||
Class which defines the form for a new Item in an Order
|
Class which defines the form for a new Item in an Order
|
||||||
For Users who aren't logged in
|
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:
|
def populate(self, location: Location) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -80,8 +82,11 @@ class AnonOrderItemForm(OrderItemForm):
|
||||||
the name of the anon user
|
the name of the anon user
|
||||||
"""
|
"""
|
||||||
OrderItemForm.populate(self, location)
|
OrderItemForm.populate(self, location)
|
||||||
if self.name.data is None:
|
if not self.is_submitted():
|
||||||
self.name.data = session.get("anon_name", None)
|
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:
|
def validate(self) -> bool:
|
||||||
"Check if the provided anon_name is not already taken"
|
"Check if the provided anon_name is not already taken"
|
||||||
|
@ -90,8 +95,8 @@ class AnonOrderItemForm(OrderItemForm):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# check if we have a user with this name
|
# 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:
|
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 False
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -42,9 +42,6 @@
|
||||||
{% if form -%}
|
{% if form -%}
|
||||||
<div class="col-md-push-1 col-md-10 darker order_order" id="form">
|
<div class="col-md-push-1 col-md-10 darker order_order" id="form">
|
||||||
<h4>Order:</h4>
|
<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) }}">
|
<form method="post" action="{{ url_for('order_bp.order_item_create', order_id=order.id) }}">
|
||||||
<span class="pull-right">
|
<span class="pull-right">
|
||||||
<a class="btn btn-primary" onclick="chooseRandom()">Choose for me</a>
|
<a class="btn btn-primary" onclick="chooseRandom()">Choose for me</a>
|
||||||
|
@ -83,10 +80,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if current_user.is_anonymous() %}
|
{% if current_user.is_anonymous() %}
|
||||||
<div class="form-group{{ ' has-error' if form.name.errors }}{{ ' required' if form.name.flags.required }}">
|
<div class="form-group{{ ' has-error' if form.user_name.errors }}{{ ' required' if form.user_name.flags.required }}">
|
||||||
{{ form.name.label(class='control-label') }}
|
{{ form.user_name.label(class='control-label') }}
|
||||||
{{ form.name(class='form-control', placeholder='Fill in your name...') }}
|
{{ form.user_name(class='form-control', placeholder='Fill in your name...') }}
|
||||||
{{ util.render_form_field_errors(form.name) }}
|
{{ util.render_form_field_errors(form.user_name) }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="form-group" style="padding-top: 8px;">
|
<div class="form-group" style="padding-top: 8px;">
|
||||||
|
@ -96,7 +93,6 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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")
|
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):
|
if dish_id and not location.dish_by_id(dish_id):
|
||||||
abort(404)
|
abort(404)
|
||||||
form.dish_id.data = dish_id
|
if not form.is_submitted():
|
||||||
|
form.dish_id.data = dish_id
|
||||||
form.populate(current_order.location)
|
form.populate(current_order.location)
|
||||||
|
|
||||||
# If the form was not submitted (GET request), the form had errors,
|
if form.is_submitted():
|
||||||
# or the dish was changed: show form again
|
form_for_dish = request.form.get("form_for_dish_id")
|
||||||
dish_was_changed = request.form.get("form_for_dish_id") and request.form["form_for_dish_id"] != dish_id
|
dish_was_changed = form_for_dish is not None and form_for_dish != dish_id
|
||||||
if not form.validate_on_submit() or dish_was_changed:
|
|
||||||
|
# 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)
|
return order_from_id(order_id, form=form, dish_id=dish_id)
|
||||||
|
|
||||||
# Form was submitted and is valid
|
# 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()
|
item = OrderItem()
|
||||||
form.populate_obj(item)
|
form.populate_obj(item)
|
||||||
item.hlds_data_version = location_definition_version
|
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():
|
if not current_user.is_anonymous():
|
||||||
item.user_id = current_user.id
|
item.user_id = current_user.id
|
||||||
else:
|
else:
|
||||||
session["anon_name"] = item.name
|
session["anon_name"] = item.user_name
|
||||||
|
|
||||||
# XXX Temporary until OrderItemChoice is used
|
# XXX Temporary until OrderItemChoice is used
|
||||||
def _name(option):
|
def _name(option):
|
||||||
|
no_text_tag = "no_text"
|
||||||
try:
|
try:
|
||||||
|
if not option or no_text_tag in option.tags:
|
||||||
|
return None
|
||||||
return option.name
|
return option.name
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return ", ".join(o.name for o in option)
|
return ", ".join(o.name for o in option if no_text_tag not in o.tags)
|
||||||
comments = [_name(option) for option in chosen if option and "no_text" not in option.tags]
|
comments = list(ignore_none(_name(option) for option in chosen))
|
||||||
if item.comment:
|
if item.comment:
|
||||||
comments.append("Comment: " + item.comment)
|
comments.append("Comment: " + item.comment)
|
||||||
item.comment = "; ".join(comments)
|
item.comment = "; ".join(comments)
|
||||||
|
@ -221,7 +232,7 @@ def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]:
|
||||||
).all()
|
).all()
|
||||||
else:
|
else:
|
||||||
items = OrderItem.query.filter(
|
items = OrderItem.query.filter(
|
||||||
(OrderItem.name == user_name) & (OrderItem.order_id == order_id)
|
(OrderItem.user_name == user_name) & (OrderItem.order_id == order_id)
|
||||||
).all()
|
).all()
|
||||||
current_order = Order.query.filter(Order.id == order_id).first()
|
current_order = Order.query.filter(Order.id == order_id).first()
|
||||||
for item in items:
|
for item in items:
|
||||||
|
|
Loading…
Reference in a new issue