haldis/app/templates/order.html

499 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "layout.html" %}
{% set active_page = "orders" -%}
{% if current_user.is_anonymous() %}
{% set my_items = order.for_user(anon=session.get("anon_name", "")) %}
{% else %}
{% set my_items = order.for_user(user=current_user) %}
{% endif %}
{% set courier_or_admin = not current_user.is_anonymous() and (current_user.is_admin() or current_user.id == order.courier_id) -%}
{% import "utils.html" as util %}
{% block container %}
<header>
<h2 id="order-title">Order {{ order.id }}</h2>
<div class="location">
{% if order.location %}
<a href="{{ url_for('general_bp.location', location_id=order.location_id) }}">{{ order.location_name }}</a>
{% else %}
{{ order.location_name }}
{% endif %}
</div>
</header>
<section>
<div class="box" id="order_info">
<h3>Order information</h3>
<dl>
<dt>Location</dt>
<dd>
{% if order.location %}
<a href="{{ url_for('general_bp.location', location_id=order.location_id) }}">{{ order.location_name }}</a>
{% else %}
{{ order.location_name }}
{% endif %}
</dd>
<dt>Delivery at</dt>
<dd>
Zeuskelder <b>TODO</b>
</dd>
<dt>Courier</dt>
<dd>
{% if order.courier == None %}
{% if not current_user.is_anonymous() %}
<form action="{{ url_for('order_bp.volunteer', order_id=order.id) }}" method="post" style="display:inline">
<input type="submit" class="btn btn-primary btn-sm" value="Volunteer"></input>
</form>
{% else %}No-one{% endif %}
{% else %}
{{ order.courier.username }}
{% endif %}
</dd>
<br/>
<br/>
<dt>Opens</dt>
<dd>{{ order.starttime.strftime("%d/%m/%Y %H:%M") }}</dd>
<dt>Closes</dt>
<dd>
{% if order.stoptime %}
{{ order.stoptime.strftime("%H:%M") }} ({{ order.stoptime|countdown }})
{% else %}
Never
{% endif %}
</dd>
</dl>
<div>
{% if order.can_close(current_user.id) -%}
<form action="{{ url_for('order_bp.close_order', order_id=order.id) }}" method="post" style="display:inline">
<input type="submit" class="btn btn-danger" value="Close"></input>
</form>
{% endif %}
{% if courier_or_admin %}
<a class="btn" href="{{ url_for('order_bp.order_edit', order_id=order.id) }}">Edit</a>
{%- endif %}
</div>
</div><!--
-->{% if form %}<!--
--><div class="box" id="add_item">
<h3>Add item to order</h3>
<form method="post" action="{{ url_for('order_bp.order_item_create', order_id=order.id) }}">
{{ form.csrf_token }}
<input type="hidden" name="form_for_dish" value="{{ dish.id }}" />
<div class="form-group select2-container select2 {{ 'has-errors' if form.dish_id.errors}}">
{{ form.dish_id.label }}<br>
{{ form.dish_id(class='form-control select') }}
{{ util.render_form_field_errors(form.dish_id) }}
</div>
<div id="dish_choices">
{% if dish and dish.choices %}
{% for (choice_type, choice) in dish.choices %}
<div class="form-group select2-container select2">
<label class="control-label" for="choice_{{ choice.id }}">{{ choice.name }}</label><br/>
<select
{{ "multiple=multiple" if choice_type=="multi_choice" else "required=required" }}
name="choice_{{ choice.id }}"
class="form-control select">
{% for option in choice.options %}
<option value="{{ option.id }}"><!--
-->{{ option.name }}{{ ": " + option.price|euro if option.price else "" }}<!--
-->{{ " (" + option.description + ")" if option.description else "" }}<!--
--></option>
{% endfor %}
</select>
</div>
{% endfor %}
{% endif %}
</div>
<div class="form-group {{ 'has-errors' if form.dish_id.errors }}">
{{ form.comment.label }}<br>
{{ form.comment(class='form-control', placeholder='Fill in comment, when applicable') }}
{{ util.render_form_field_errors(form.comment) }}
</div>
{% if current_user.is_anonymous() %}
<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;">
<a class="btn" onclick="chooseRandom();">Random</a>
{{ form.submit_button(class='btn btn-primary') }}
{% if not dish %}
<div id="submit-reveals-options-msg">If the chosen dish has options, they will be shown when you press submit, before adding the item to the order.</div>
{% endif %}
</div>
</form>
</div><!--
--><div class="box" id="from_history">
<h3>Add from history</h3>
<ul>
<li>Todo</li>
</ul>
</div><!--
-->{% endif %}<!--
--><div class="box" id="my_items">
<h3>My items</h3>
{% if my_items %}
<ul>
{% for item in my_items %}
<li>
{% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%}
<form action="{{ url_for('order_bp.delete_item', order_id=order.id, item_id=item.id) }}" method="post" style="display:inline">
<button class="btn btn-link btn-sm" type="submit" style="padding: 0 0.5em;"><span class="glyphicon glyphicon-remove"></span></button>
</form>
{%- endif %}
<span class="price_aligned">{{ item.price|euro }}</span> {{ item.dish_name }}{% if item.comment %}; {{ item.comment }}{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<div>(None)</div>
{% endif %}
</div>
</section>
<section>
<div class="box" id="per_dish">
<h3>Ordered dishes</h3>
{% for dish_name, dish_order_items in order.group_by_dish() -%}
{% set has_comments = dish_order_items | map(attribute="comment") | any -%}
<div class="dish {{ 'no_comments' if not has_comments }}">
<h4>
<span class="quantity">{{ dish_order_items | length }}</span> ×
{{ dish_name }}
</h4>
{% if has_comments -%}
<ul class="comments">
{% for item in dish_order_items -%}
<li>{% if item["comment"] %}<span>{{ item["comment"] }}</span>
{% else %}<i>No comment</i>
{% endif %}<span class="spacer"> </span><span class="item_for">for {{ item.for_name }}</span></li>
{% endfor %}
</ul>
{% else %}
<span class="spacer"> </span><span class="item_for">for {{ dish_order_items | map(attribute="for_name") | join(", ") }}</span>
{%- endif %}
</p>
</div>
{%- endfor %}
<div class="footer">
Total {{ order.items.count() }} items — {{ total_price|euro }}
<a class="btn" href="{{ url_for('order_bp.items_showcase', order_id=order.id) }}">Shop view</a>
</div>
</div><!--
--><div class="box" id="how_to_order">
<h3>Ordering at {{ order.location_name }}</h3>
<dl>
{% if order.location.telephone %}
<dt>Telephone</dt>
<dd><a href="tel://{{ order.location.telephone }}">{{ order.location.telephone }}</a></dd>
{% endif %}
{% if order.location.website %}
<dt>Website</dt>
<dd><a href="{{ order.location.website }}">{{ order.location.website }}</a></dd>
{% endif %}
{% if order.location.address or order.location.osm %}
<dt>Location</dt>
<dd>
{% if order.location.osm %}
<a href="{{ order.location.osm }}">{{ order.location.address or "View on OSM" }}</a>
{% else %}
{{ order.location.address }}
{% endif %}
</dd>
{% endif %}
</dl>
<b>TODO Only show options that allow you to order</b>
</div>
</section>
<section class="single_column">
<div class="box" id="per_person">
<h3>Items per person</h3>
<table class="table table-condensed">
<thead>
<tr><th>Total</th><th>Name</th><th>Items</th></tr>
</thead>
<tbody>
{% for user_name, order_items in order.group_by_user() -%}
<tr>
<td>
{% set paid = order_items | map(attribute="paid") | all %}
<input type="checkbox" name="{{ user_name }}"
{{ "disabled" if paid }} style="{{ 'opacity: 0.5' if paid }}">
<span class="price">{{ order_items | map(attribute="price") | sum | euro }}</span>
{% if paid %}paid{% endif %}
</td>
<td>{{ user_name }}</td>
<td class="items">
<ul>
{% for item in order_items %}
<li class="{{ 'paid' if item.paid }}">
<div class="actions">
{% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%}
<form action="{{ url_for('order_bp.delete_item', order_id=order.id, item_id=item.id) }}" method="post" style="display:inline">
<button class="btn btn-link btn-sm" type="submit" style="padding: 0 0.5em;"><span class="glyphicon glyphicon-remove"></span></button>
</form>
{% else %}
<span class="glyphicon glyphicon-remove" style="color: var(--dGray3); padding: 0 0.5em"></span>
{%- endif %}
</div>
<div class="price_aligned">{{ item.price|euro }}</div>
<div class="item_description">{{ item.dish_name }}{{ "; " + item.comment if item.comment }}</div>
</li>
{% endfor %}
<li>
<button class="btn btn-link btn-sm" onclick="alert('TODO')" style="padding: 0 0.5em;"><span class="glyphicon glyphicon-plus"></span></button>
</li>
</ul>
</td>
</tr>
{%- endfor %}
</tbody>
</table>
<div class="footer">
On selected:
<button class="btn btn-sm">Mark paid (TODO)</button>
Request payment for selected:
<button class="btn btn-sm"><span class="glyphicon glyphicon-piggy-bank"></span> Tab (TODO)</button>
<button class="btn btn-sm"><span class="glyphicon glyphicon-qrcode"></span> QR code (TODO)</button>
</div>
</div>
</section>
{% endblock %}
{% block styles %}
{{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='css/select2.min.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/select2-bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/print.css') }}">
<style>
body, h1, h2, h3, h4 {
color: var(--dGray0);
}
table {
overflow-wrap: break-word;
}
section {
column-count: 2;
column-gap: 50px;
}
section.single_column {
column-count: unset;
}
header {
margin-bottom: 25px;
}
h2 {
margin-bottom: 0;
}
h3 {
margin-top: 0;
}
.location {
font-size: 125%;
font-weight: 500;
margin-left: 2px;
margin-top: -5px;
}
.box {
display: inline-block;
vertical-align: top;
width: 100%;
border: 2px solid var(--dGray0);
padding: 10px;
margin-bottom: 50px;
}
#order_info dl {
column-width: 150px;
}
#from_history ul, #my_items ul, #per_person ul {
list-style-type: none;
padding: 0;
}
dl {
margin-bottom: 10px;
}
.box :last-child {
margin-bottom: 0;
}
.box h4 {
font-size: 110%;
font-weight: bold;
margin-bottom: 0.6em;
}
#per_dish .dish.no_comments {
display: flex;
align-items: flex-end;
}
#per_dish .dish.no_comments h4 {
margin-bottom: 0;
line-height: inherit;
}
#per_dish .comments li {
display: flex;
align-items: flex-end;
line-height: 1.5;
margin: 0.3em 0;
}
#per_dish .spacer {
content: ' ';
flex-grow: 1;
min-width: 10px;
border-bottom: 1px solid var(--dGray3);
margin: 0.3em 0.5em;
}
#per_dish .item_for {
color: var(--dGray2);
text-align: right;
}
#per_person li {
white-space: nowrap;
margin: 0;
vertical-align: top;
}
#per_person li > * {
display: inline-block;
vertical-align: top;
}
#per_person .item_description {
white-space: normal;
}
.price, .price_aligned {
white-space: nowrap;
}
.price_aligned {
display: inline-block;
width: 4em;
}
.items .paid {
opacity: 0.4;
}
.footer {
margin-top: 1em;
}
</style>
{% endblock %}
{% block scripts %}
{{ super() }}
<script src="{{ url_for('static', filename='js/select2.min.js') }}"></script>
<script type="text/javascript">
{% if form %}
function sortArg(sortable) {
return sortable.sort();
}
var select = $(".select").select2({"sorter": sortArg});
var options = select[0].options;
function chooseRandom() {
var index = Math.floor((Math.random() * options.length))
var choice = options[index]
select.val(choice.value).trigger("change")
}
{% endif %}
{% if form and order.location %}
function updateChoices() {
$("#submit-reveals-options-msg").hide(0);
$dish_choices = $("#dish_choices");
$dish_choices.addClass("loading");
var dish_id = $("#dish_id").val();
var url = "{{ url_for('general_bp.location_dish', location_id=order.location.id, dish_id='DISHID') }}".replace("DISHID", encodeURI(dish_id));
$dish_choices.find("select").attr("disabled", "disabled");
$.get(url)
.done(function(data) {
$dish_choices.html("");
for (var i in data) {
var choice = data[i];
var id = "choice_" + choice["id"];
var label = $("<label class='control-label'/>")
.attr("for", id)
.text(choice["name"] +
(choice["price"] ? ": € " + choice["price"] / 100 : "") +
(choice["description"] ? " (" + choice["description"] + ")" : "")
);
var choiceSelect = $("<select class='form-control select' />")
.attr("id", id)
.attr("name", id);
if (choice.type === "multi_choice") {
choiceSelect.attr("multiple", "multiple");
} else {
choiceSelect.attr("required", "required");
}
for (var j in choice["options"]) {
var option = choice["options"][j];
choiceSelect.append(
$("<option />").text(
option["name"] +
(option["price"] ? ": € " + option["price"] / 100 : "") +
(option["description"] ? " (" + option["description"] + ")" : "")
).attr("value", option["id"])
);
}
$dish_choices
.append(
$("<div class='form-group select2-container select2'>")
.append(label, "<br/>", choiceSelect),
" "
);
choiceSelect.select2({"sorter": sortArg});
}
$dish_choices.removeClass("loading");
}).fail(function() {
$("#dish_choices").html("Could not load choices");
$dish_choices.removeClass("loading");
$("#submit-reveals-options-msg").show(0);
});
}
$("#dish_id").on("change", updateChoices);
updateChoices();
{% endif %}
</script>
{% endblock %}