Support marking items as paid
This commit is contained in:
parent
0ace54a8fd
commit
fc630e9061
3 changed files with 64 additions and 26 deletions
|
@ -73,3 +73,12 @@ class OrderItem(db.Model):
|
||||||
if user and (user.is_admin() or user == self.order.courier):
|
if user and (user.is_admin() or user == self.order.courier):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# pylint: disable=W0613
|
||||||
|
def can_modify_payment(self, order_id: int, user_id: int) -> bool:
|
||||||
|
if int(self.order_id) != int(order_id):
|
||||||
|
return False
|
||||||
|
user = User.query.filter(User.id == user_id).first()
|
||||||
|
if user and (user.is_admin() or user == self.order.courier):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
|
@ -267,6 +267,7 @@
|
||||||
<section class="single_column">
|
<section class="single_column">
|
||||||
<div class="box" id="per_person">
|
<div class="box" id="per_person">
|
||||||
<h3>Items per person</h3>
|
<h3>Items per person</h3>
|
||||||
|
<form action="{{ url_for('order_bp.items_user_paid', order_id=order.id) }}" method="post">
|
||||||
<table class="table table-condensed">
|
<table class="table table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr><th>Total</th><th>Name</th><th>Items</th></tr>
|
<tr><th>Total</th><th>Name</th><th>Items</th></tr>
|
||||||
|
@ -276,12 +277,20 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{% set paid = order_items | map(attribute="paid") | all %}
|
{% set paid = order_items | map(attribute="paid") | all %}
|
||||||
<input type="checkbox" name="{{ user_name }}"
|
{% set can_modify_payment = True %}
|
||||||
{{ "disabled" if paid }} style="{{ 'opacity: 0.5' if paid }}">
|
{% for order_item in order_items %}
|
||||||
|
{% if not order_item.can_modify_payment(order.id, current_user.id) %}
|
||||||
|
{% set can_modify_payment = False %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
<input type="checkbox" name="user_names" value="{{ user_name }}"
|
||||||
|
{{ "disabled" if not can_modify_payment }}>
|
||||||
|
|
||||||
<span class="price">{{ order_items | map(attribute="price") | sum | euro }}</span>
|
<span class="price" style="{{ 'opacity: 0.5' if paid }}">
|
||||||
|
{{ order_items | map(attribute="price") | sum | euro }}
|
||||||
|
</span>
|
||||||
|
|
||||||
{% if paid %}paid{% endif %}
|
{% if paid %}<span class="glyphicon glyphicon-ok"></span>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ user_name }}</td>
|
<td>{{ user_name }}</td>
|
||||||
<td class="items">
|
<td class="items">
|
||||||
|
@ -315,10 +324,12 @@
|
||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
On selected:
|
On selected:
|
||||||
<button class="btn btn-sm"><span class="glyphicon glyphicon-ok"></span> Mark paid (TODO)</button>
|
<button name="action" value="mark_paid" class="btn btn-sm"><span class="glyphicon glyphicon-ok"></span> Mark paid</button>
|
||||||
<button class="btn btn-sm"><span class="glyphicon glyphicon-piggy-bank"></span> Tab (TODO)</button>
|
<button name="action" value="mark_unpaid" class="btn btn-sm">Mark unpaid</button>
|
||||||
<button class="btn btn-sm"><span class="glyphicon glyphicon-qrcode"></span> QR code (TODO)</button>
|
<button disabled name="action" value="tab" class="btn btn-sm"><span class="glyphicon glyphicon-piggy-bank"></span> Tab (TODO)</button>
|
||||||
|
<button disabled name="action" value="qr" class="btn btn-sm"><span class="glyphicon glyphicon-qrcode"></span> QR code (TODO)</button>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -225,11 +225,22 @@ def order_item_create(order_id: int) -> typing.Any:
|
||||||
return redirect(url_for("order_bp.order_from_id", order_id=order_id))
|
return redirect(url_for("order_bp.order_from_id", order_id=order_id))
|
||||||
|
|
||||||
|
|
||||||
@order_bp.route("/<order_id>/<user_name>/user_paid", methods=["POST"])
|
@order_bp.route("/<order_id>/users_paid", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
# pylint: disable=R1710
|
# pylint: disable=R1710
|
||||||
def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]:
|
def items_user_paid(order_id: int) -> typing.Optional[Response]:
|
||||||
"Indicate payment status for a user in an order"
|
user_names = request.form.getlist("user_names")
|
||||||
|
if request.form.get("action") == "mark_paid":
|
||||||
|
return set_items_paid(order_id, user_names, True)
|
||||||
|
elif request.form.get("action") == "mark_unpaid":
|
||||||
|
return set_items_paid(order_id, user_names, False)
|
||||||
|
else:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
def set_items_paid(order_id: int, user_names: typing.Iterable[str], paid: bool):
|
||||||
|
total_paid_items = 0
|
||||||
|
total_failed_items = 0
|
||||||
|
for user_name in user_names:
|
||||||
user = User.query.filter(User.username == user_name).first()
|
user = User.query.filter(User.username == user_name).first()
|
||||||
items: typing.List[OrderItem] = []
|
items: typing.List[OrderItem] = []
|
||||||
if user:
|
if user:
|
||||||
|
@ -240,14 +251,21 @@ def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]:
|
||||||
items = OrderItem.query.filter(
|
items = OrderItem.query.filter(
|
||||||
(OrderItem.user_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()
|
|
||||||
if current_order.courier_id == current_user.id or current_user.admin:
|
|
||||||
for item in items:
|
for item in items:
|
||||||
item.paid = True
|
if item.can_modify_payment(order_id, current_user.id):
|
||||||
|
if item.paid != paid:
|
||||||
|
item.paid = paid
|
||||||
|
total_paid_items += 1
|
||||||
|
else:
|
||||||
|
total_failed_items += 1
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash("Paid %d items for %s" % (len(items), item.for_name), "success")
|
if total_failed_items == 0:
|
||||||
|
flash("Marked %d items as paid" % (total_paid_items,), "success")
|
||||||
|
else:
|
||||||
|
flash("Failed to mark %d items as paid (succeeded in marking %d items as paid)" % (total_failed_items, total_paid_items), "error")
|
||||||
return redirect(url_for("order_bp.order_from_id", order_id=order_id))
|
return redirect(url_for("order_bp.order_from_id", order_id=order_id))
|
||||||
abort(404)
|
|
||||||
|
|
||||||
|
|
||||||
@order_bp.route("/<order_id>/<item_id>/delete", methods=["POST"])
|
@order_bp.route("/<order_id>/<item_id>/delete", methods=["POST"])
|
||||||
|
|
Loading…
Reference in a new issue