diff --git a/app/forms.py b/app/forms.py index 86bb9c1..08f42f3 100644 --- a/app/forms.py +++ b/app/forms.py @@ -50,8 +50,6 @@ class OrderItemForm(Form): "New Item in an Order" # pylint: disable=R0903 dish_id = SelectField("Dish") - single_choices = FieldList(SelectField()) - multi_choices = FieldList(SelectMultipleField()) comment = StringField("Comment") submit_button = SubmitField("Submit") @@ -60,29 +58,6 @@ class OrderItemForm(Form): (i.id, (i.name + ": " + euro_string(i.price))) for i in location.dishes ] - dish = location.dish_by_id(dish_id) if dish_id else None - if dish: - self.add_choices_for(dish) - - def add_choices_for(self, dish: Dish): - for (choice_type, choice) in dish.choices: - if choice_type == "single_choice": - field = self.single_choices.append_entry(choice.name) - elif choice_type == "multi_choice": - field = self.multi_choices.append_entry(choice.name) - else: - assert False, "Unsupported choice type" - field.label.text = choice.name - field.choices = self.options_for(choice) - - @staticmethod - def options_for(choice: Choice): - return [ - (c.id, (c.name + - (" (" + c.description + ")" if c.description else "") + - (": +" + euro_string(c.price) if c.price else ""))) - for c in choice.options - ] class AnonOrderItemForm(OrderItemForm): diff --git a/app/hlds/models.py b/app/hlds/models.py index 2a1161d..43cac53 100644 --- a/app/hlds/models.py +++ b/app/hlds/models.py @@ -54,6 +54,9 @@ class Choice: "\n\t\t".join(map(str, self.options)) ) + def option_by_id(self, option_id: str) -> Optional[Option]: + return first(filter(lambda o: o.id == option_id, self.options)) + class Dish: def __init__(self, id_, *, name, description, price, tags, choices): diff --git a/app/templates/order.html b/app/templates/order.html index 37a6f88..ed4271d 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -52,26 +52,32 @@ {{ form.dish_id(class='form-control select') }} {{ util.render_form_field_errors(form.dish_id) }} + + {% if dish and dish.choices %} + {% for (choice_type, choice) in dish.choices %} +
+
+ +
+ {% endfor %} + {% endif %} +
{{ form.comment.label(class='control-label') }}
{{ form.comment(class='form-control', placeholder='Fill in comment, when applicable') }} {{ util.render_form_field_errors(form.comment) }}
- {% for choice_field in form.single_choices %} -
- {{ choice_field.label(class='control-label') }}
- {{ choice_field(class='form-control') }} - {{ util.render_form_field_errors(choice_field) }} -
- {% endfor %} - {% for choice_field in form.multi_choices %} -
- {{ choice_field.label(class='control-label') }}
- {{ choice_field(class='form-control') }} - {{ util.render_form_field_errors(choice_field) }} -
- {% endfor %} {% if current_user.is_anonymous() %}
{{ form.name.label(class='control-label') }} diff --git a/app/views/order.py b/app/views/order.py index a36b5c7..4e0658a 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -47,7 +47,7 @@ def order_create() -> typing.Union[str, Response]: @order_bp.route("/") -def order_from_id(order_id: int, form: OrderForm = None) -> str: +def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: "Generate order view from id" order = Order.query.filter(Order.id == order_id).first() if order is None: @@ -64,8 +64,11 @@ def order_from_id(order_id: int, form: OrderForm = None) -> str: form = None total_price = sum([o.price for o in order.items]) debts = sum([o.price for o in order.items if not o.paid]) + + dish = order.location.dish_by_id(dish_id) if order.location else None + return render_template("order.html", order=order, form=form, - total_price=total_price, debts=debts) + total_price=total_price, debts=debts, dish=dish) @order_bp.route("//items") @@ -122,26 +125,29 @@ def order_item_create(order_id: int) -> typing.Any: form = AnonOrderItemForm() if current_user.is_anonymous() \ else OrderItemForm() - dish_id = form.dish_id.data if form.is_submitted() else request.args.get("dish") + dish_id_in_url = request.args.get("dish") + dish_id = form.dish_id.data if form.is_submitted() else dish_id_in_url if dish_id and not location.dish_by_id(dish_id): abort(404) + form.dish_id.data = dish_id form.populate(current_order.location, dish_id) - if not form.validate_on_submit(): - return order_from_id(order_id, form=form) + # If the form was not submitted (GET request), the form had errors, or the dish was changed: show form again + if not form.validate_on_submit() or (dish_id_in_url and dish_id_in_url != dish_id): + 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 - form_data = form.data - choices = location.dish_by_id(form_data["dish_id"]).choices - all_choices_present = all( - ("choice_" + choice.id) in form_data + choices = location.dish_by_id(form.dish_id.data).choices + chosen = [ + choice.option_by_id(request.form.get("choice_" + choice.id)) for (_choice_type, choice) in choices - ) + ] + all_choices_present = all(chosen) if not all_choices_present: return redirect(url_for("order_bp.order_item_create", - order_id=order_id, dish=form_data["dish_id"])) + order_id=order_id, dish=form.dish_id.data)) item = OrderItem() form.populate_obj(item) @@ -150,6 +156,11 @@ def order_item_create(order_id: int) -> typing.Any: item.user_id = current_user.id else: session["anon_name"] = item.name + + # XXX Temporary + chosen_text = "; ".join(option.name for option in chosen) + item.comment = chosen_text + "; Comment: " + item.comment if item.comment else chosen_text + item.update_from_hlds() db.session.add(item) db.session.commit()