diff --git a/app/app.py b/app/app.py index 1a3dd98..1070142 100755 --- a/app/app.py +++ b/app/app.py @@ -171,6 +171,7 @@ def add_template_filters(app: Flask) -> None: app.template_filter("euro")(euro_string) app.template_filter("price_range")(price_range_string) app.template_filter("any")(any) + app.template_filter("all")(all) app = Flask(__name__) diff --git a/app/models/order.py b/app/models/order.py index 6ad5b5f..705470f 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -44,35 +44,48 @@ class Order(db.Model): ), "location_id must be configured before updating from HLDS" self.location_name = self.location.name - def group_by_user(self) -> typing.Dict[str, typing.Any]: + def for_user(self, anon=None, user=None) -> typing.List: + return list( + filter( + (lambda i: i.user == user) + if user is not None + else (lambda i: i.user_name == anon), + self.items + ) + ) + + def group_by_user(self) -> typing.List[typing.Tuple[str, typing.List]]: "Group items of an Order by user" - group: typing.Dict[str, typing.Any] = dict() + group: typing.Dict[str, typing.List] = dict() + for item in self.items: - user = group.get(item.get_name(), dict()) - user["total"] = user.get("total", 0) + item.price - user["to_pay"] = user.get("to_pay", 0) + item.price if not item.paid else 0 - user["paid"] = user.get("paid", True) and item.paid - user["dishes"] = user.get("dishes", []) + [item.dish_name] - group[str(item.get_name())] = user + if item.for_name not in group: + group[item.for_name] = [] - return group + group[item.for_name].append(item) - def group_by_dish( - self, sort_comments=False - ) -> typing.Dict[str, typing.Dict[str, typing.Any]]: + for _user_name, order_items in group.items(): + order_items.sort(key=lambda order_item: order_item.comment or "") + + return list(sorted(group.items())) + + def group_by_dish(self) -> typing.List[typing.Tuple[str, typing.List]]: "Group items of an Order by dish" - group: typing.Dict[str, typing.Dict[str, typing.Any]] = dict() + group: typing.Dict[str, typing.List] = dict() + for item in self.items: - dish = group.get(item.dish_name, dict()) - dish["count"] = dish.get("count", 0) + 1 - dish["comments"] = dish.get("comments", []) + [item.comment] - group[item.dish_name] = dish + if item.dish_name not in group: + group[item.dish_name] = [] - if sort_comments: - for _dish_name, dish_props in group.items(): - dish_props["comments"].sort() + group[item.dish_name].append(item) - return group + for _dish_name, order_items in group.items(): + order_items.sort(key=lambda order_item: ( + (order_item.comment or " No comment") + + (order_item.for_name) + )) + + return list(sorted(group.items())) def is_closed(self) -> bool: return self.stoptime and datetime.now() > self.stoptime diff --git a/app/models/orderitem.py b/app/models/orderitem.py index a078086..253cd85 100644 --- a/app/models/orderitem.py +++ b/app/models/orderitem.py @@ -37,7 +37,8 @@ class OrderItem(db.Model): raise ValueError("No Location found with id: " + location_id) raise AttributeError() - def get_name(self) -> str: + @property + def for_name(self) -> str: "Get the name of the user which 'owns' the item" if self.user_id is not None and self.user_id > 0: return self.user.username @@ -46,7 +47,7 @@ class OrderItem(db.Model): def __repr__(self) -> str: return "Order %d: %s wants %s" % ( self.order_id or 0, - self.get_name(), + self.for_name, self.dish_name or "None", ) diff --git a/app/static/css/main.css b/app/static/css/main.css index d5dc8b6..2fd83df 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -1,16 +1,15 @@ -/* Custom CSS */ :root { - /*Darkmode colors*/ - --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; - --FontFamily:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; - --FontSize:13px; + /* Darkmode colors */ + --dGray0: #D0D0D8; + --dGray1: #8E8E93; + --dGray2: #636366; + --dGray3: #48484A; + --dGray4: #3A3A3C; + --dGray5: #2C2C2E; + --dGray6: #1C1C1E; + --dBlue: #0A84FF; + --FontFamily: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; + --FontSize: 13px; } html { @@ -26,7 +25,7 @@ body { font-size: var(--FontSize); } -.background{ +.background { position: absolute; z-index: -1000; top: 0; @@ -47,12 +46,6 @@ body { padding-top: 10px; } -.darker { - background-color: #fafafa; - margin-top: 10px; - padding-bottom: 5px; -} - @media (min-width: 992px) { .align-bottom { margin-top: 2.5em; @@ -121,10 +114,6 @@ body { margin-top: 1.3em; } -.order_row { - background: var(--dGray4); -} - .time_data{ display: flex; justify-content: space-between; @@ -144,14 +133,6 @@ body { } } -/* Add clickable box */ -div.box:hover { - cursor: hand; - cursor: pointer; - opacity: .9; - box-shadow: 2px 4px 4px -1px #888888; -} - a.divLink { position: absolute; width: 100%; @@ -198,18 +179,25 @@ a { .navbar { background-color: var(--dGray6); } -.navbar-default .navbar-nav .active a{ - background-color: var(--dGray4); +.navbar-default .navbar-nav .active a { + background-color: var(--dGray5); color: var(--dGray1); } -.navbar-default .navbar-nav .active a:hover{ - background-color: var(--dGray3); +.navbar-default .navbar-nav .active a:hover, +.navbar-default .navbar-nav .active a:focus, +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + background-color: var(--dGray4); color: var(--dGray0); } -.navbar-default .navbar-nav li a,.navbar-default .navbar-brand{ +.navbar-default .navbar-nav li a, +.navbar-default .navbar-brand { color: var(--dGray1); } -.navbar-default .navbar-nav li a:hover,.navbar-default .navbar-brand:hover{ +.navbar-default .navbar-nav li a:hover, +.navbar-default .navbar-nav li a:focus, +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { color: var(--dGray0); } hr{ @@ -220,9 +208,16 @@ h1, h2, h3, h4, h5, h6{ color: var(--dGray1); } -.jumbotron, .darker { - background-color: var(--dGray4); +.jumbotron, .darker, .order_row { + background: var(--dGray4); } + +.darker { + margin-top: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + .table tbody tr td { border-top: 1px solid var(--dGray3); } @@ -287,9 +282,6 @@ h1, h2, h3, h4, h5, h6{ .form-control::placeholder{ color: var(--dGray2); } -.enter_darkmode>a { - text-align: center; -} #dish_choices { margin: 0.5em 1em 1.5em; diff --git a/app/static/css/themes/plain_lightmode.css b/app/static/css/themes/plain_lightmode.css index 4713231..cb6baf7 100644 --- a/app/static/css/themes/plain_lightmode.css +++ b/app/static/css/themes/plain_lightmode.css @@ -1,10 +1,10 @@ :root { - --dGray0:#444444; - --dGray1:#666666; - --dGray2:#212121; - --dGray3:#ffffff; - --dGray4:#f9f9f9; - --dGray5:#ffffff; + --dGray0:#212121; + --dGray1:#444444; + --dGray2:#666666; + --dGray3:#cccccc; + --dGray4:#f1f1f1; + --dGray5:#f8f8f8; --dGray6:#ffffff; --dBlue:#0A84FF; } diff --git a/app/templates/order.html b/app/templates/order.html index 25a3f8a..2cbfc65 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -1,82 +1,123 @@ {% extends "layout.html" %} {% set active_page = "orders" -%} -{% set order_items = order.group_by_user() -%} +{% 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 %} -
Name | Item | Price | {% if courier_or_admin %}Paid? | {% endif %}Delete | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
{{ item.get_name() }} | -{{ item.dish_name }}{{ "*" if item.comment }} | -{{ item.price|euro }} | - {% if courier_or_admin %} -- {% if not item.paid %} - - {% else %} - {% endif %} - | - {% endif %} -
+
+ {% endif %}Add from history+
+ My items+ {% if my_items %} +
|
+ {%- endif %}
+ {{ item.price|euro }} {{ item.dish_name }}{% if item.comment %}; {{ item.comment }}{% endif %}
+
+ {% endfor %}
+
+ {% else %}
+
Total | Name | Items |
---|---|---|
+ {% set paid = order_items | map(attribute="paid") | all %} + + + {{ order_items | map(attribute="price") | sum | euro }} + + {% if paid %}paid{% endif %} + | +{{ user_name }} | +
+
|
+
Name | Total | To pay | {% if courier_or_admin %}Paid? | {% endif %}
---|---|---|---|
{{ key }} | -{{ value["total"]|euro }} | -{{ value["to_pay"]|euro }} | - {% if courier_or_admin %} -- {% if not value["to_pay"] == 0 %} - - {% else %} - - {% endif %} - | - {% endif %} -
+ {{ dish_order_items | length }} × + {{ dish_name }} +
+ + {% if has_comments -%} ++ {% for item in dish_order_items -%} +- {% if item["comment"] %}{{ item["comment"] }}
+ {% else %}No comment
+ {% endif %} for {{ item.for_name }}
+ {% endfor %}
+
+ {% else %} + for {{ dish_order_items | map(attribute="for_name") | join(", ") }} + {%- endif %} + + +