mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +02:00
Merge branch 'delivery-balance' into 'master'
Basic "manage delivery balance" page See merge request ybon/copanier!5
This commit is contained in:
commit
22da3d771c
4 changed files with 91 additions and 13 deletions
|
@ -5,7 +5,7 @@ import ujson as json
|
|||
import minicli
|
||||
from jinja2 import Environment, PackageLoader, select_autoescape
|
||||
from roll import Roll, Response, HttpError
|
||||
from roll.extensions import cors, options, traceback, simple_server, static
|
||||
from roll.extensions import traceback, simple_server, static
|
||||
|
||||
from . import config, reports, session, utils, emails, loggers, imports
|
||||
from .models import Delivery, Order, Person, Product, ProductOrder
|
||||
|
@ -75,6 +75,18 @@ app = Roll()
|
|||
traceback(app)
|
||||
|
||||
|
||||
def staff_only(view):
|
||||
async def decorator(request, response, *args, **kwargs):
|
||||
user = session.user.get(None)
|
||||
if not user or not user.is_staff:
|
||||
response.message("Désolé, c'est réservé au staff par ici", "warning")
|
||||
response.redirect = request.headers.get("REFERRER", "/")
|
||||
return
|
||||
return await view(request, response, *args, **kwargs)
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
@app.listen("request")
|
||||
async def auth_required(request, response):
|
||||
# Should be handler Roll side?
|
||||
|
@ -171,6 +183,7 @@ async def new_delivery(request, response):
|
|||
|
||||
|
||||
@app.route("/livraison", methods=["POST"])
|
||||
@staff_only
|
||||
async def create_delivery(request, response):
|
||||
form = request.form
|
||||
data = {}
|
||||
|
@ -186,6 +199,7 @@ async def create_delivery(request, response):
|
|||
|
||||
|
||||
@app.route("/livraison/{id}/importer/produits", methods=["POST"])
|
||||
@staff_only
|
||||
async def import_products(request, response, id):
|
||||
delivery = Delivery.load(id)
|
||||
delivery.products = []
|
||||
|
@ -220,12 +234,14 @@ async def export_products(request, response, id):
|
|||
|
||||
|
||||
@app.route("/livraison/{id}/edit", methods=["GET"])
|
||||
@staff_only
|
||||
async def edit_delivery(request, response, id):
|
||||
delivery = Delivery.load(id)
|
||||
response.html("edit_delivery.html", {"delivery": delivery})
|
||||
|
||||
|
||||
@app.route("/livraison/{id}/edit", methods=["POST"])
|
||||
@staff_only
|
||||
async def post_delivery(request, response, id):
|
||||
delivery = Delivery.load(id)
|
||||
form = request.form
|
||||
|
@ -325,6 +341,7 @@ async def signing_sheet(request, response, id):
|
|||
|
||||
|
||||
@app.route("/livraison/{id}/importer/commande", methods=["POST"])
|
||||
@staff_only
|
||||
async def import_commande(request, response, id):
|
||||
email = request.form.get("email")
|
||||
order = Order()
|
||||
|
@ -355,14 +372,10 @@ async def xls_full_report(request, response, id):
|
|||
|
||||
|
||||
@app.route("/livraison/{id}/ajuster/{ref}", methods=["GET", "POST"])
|
||||
@staff_only
|
||||
async def adjust_product(request, response, id, ref):
|
||||
delivery = Delivery.load(id)
|
||||
delivery_url = f"/livraison/{delivery.id}"
|
||||
user = session.user.get(None)
|
||||
if not user or not user.is_staff:
|
||||
response.message("Désolé, c'est dangereux par ici", "warning")
|
||||
response.redirect = delivery_url
|
||||
return
|
||||
for product in delivery.products:
|
||||
if product.ref == ref:
|
||||
break
|
||||
|
@ -383,6 +396,22 @@ async def adjust_product(request, response, id, ref):
|
|||
response.html("adjust_product.html", {"delivery": delivery, "product": product})
|
||||
|
||||
|
||||
@app.route("/livraison/{id}/soldes", methods=["GET", "POST"])
|
||||
@staff_only
|
||||
async def delivery_balance(request, response, id):
|
||||
delivery = Delivery.load(id)
|
||||
delivery_url = f"/livraison/{delivery.id}"
|
||||
if request.method == "POST":
|
||||
form = request.form
|
||||
for email, order in delivery.orders.items():
|
||||
order.paid = form.bool(email, False)
|
||||
delivery.persist()
|
||||
response.message(f"Les soldes ont bien été mis à jour!")
|
||||
response.redirect = delivery_url
|
||||
else:
|
||||
response.html("delivery_balance.html", {"delivery": delivery})
|
||||
|
||||
|
||||
def configure():
|
||||
config.init()
|
||||
|
||||
|
|
|
@ -89,6 +89,11 @@
|
|||
{% include "includes/modal_copy_emails.html" %}
|
||||
{% endwith %}
|
||||
</li>
|
||||
{% if delivery.is_passed %}
|
||||
<li>
|
||||
<a href="/livraison/{{ delivery.id }}/soldes"><i class="icon-wallet"></i> Gérer les soldes</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endblock body %}
|
||||
|
|
20
copanier/templates/delivery_balance.html
Normal file
20
copanier/templates/delivery_balance.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<article>
|
||||
<h3><a href="/livraison/{{ delivery.id }}">{{ delivery.producer }}</a> — Gérer les soldes</h3>
|
||||
<form method="post">
|
||||
<table>
|
||||
<tr><th>Personne</th><th>Montant</th><th>Soldée</th></tr>
|
||||
{% for email, order in delivery.orders.items() %}
|
||||
<tr>
|
||||
<td>{{ email }}</td>
|
||||
<td>{{ order.total(delivery.products) }} €</td>
|
||||
<td class="with-input"><input type="checkbox" name="{{ email }}" {% if order.paid %}checked{% endif %}></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<input type="submit" value="Mettre à jour les soldes">
|
||||
</form>
|
||||
</article>
|
||||
{% endblock body %}
|
|
@ -159,15 +159,13 @@ async def test_get_adjust_product(client, delivery):
|
|||
resp = await client.get(f"/livraison/{delivery.id}/ajuster/123")
|
||||
doc = pq(resp.body)
|
||||
assert doc('[name="foo@bar.org"]')
|
||||
assert doc('[name="foo@bar.org"]').attr("value") == '1'
|
||||
assert doc('[name="foo@bar.org"]').attr("value") == "1"
|
||||
|
||||
|
||||
async def test_post_adjust_product(client, delivery):
|
||||
delivery.order_before = datetime.now() - timedelta(days=1)
|
||||
delivery.products[0].packing = 6
|
||||
delivery.orders["foo@bar.org"] = Order(
|
||||
products={"123": ProductOrder(wanted=2)}
|
||||
)
|
||||
delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)})
|
||||
delivery.persist()
|
||||
assert delivery.status == delivery.ADJUSTMENT
|
||||
body = {"foo@bar.org": "1"}
|
||||
|
@ -181,9 +179,7 @@ async def test_post_adjust_product(client, delivery):
|
|||
async def test_only_staff_can_adjust_product(client, delivery, monkeypatch):
|
||||
delivery.order_before = datetime.now() - timedelta(days=1)
|
||||
delivery.products[0].packing = 6
|
||||
delivery.orders["foo@bar.org"] = Order(
|
||||
products={"123": ProductOrder(wanted=2)}
|
||||
)
|
||||
delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)})
|
||||
delivery.persist()
|
||||
monkeypatch.setattr("copanier.config.STAFF", ["someone@else.org"])
|
||||
resp = await client.get(f"/livraison/{delivery.id}/ajuster/123")
|
||||
|
@ -196,6 +192,34 @@ async def test_only_staff_can_adjust_product(client, delivery, monkeypatch):
|
|||
assert delivery.orders["foo@bar.org"].products["123"].adjustment == 0
|
||||
|
||||
|
||||
async def test_get_delivery_balance(client, delivery):
|
||||
delivery.from_date = datetime.now() - timedelta(days=1)
|
||||
delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)})
|
||||
delivery.persist()
|
||||
resp = await client.get(f"/livraison/{delivery.id}/soldes")
|
||||
doc = pq(resp.body)
|
||||
assert doc('[name="foo@bar.org"]')
|
||||
assert not doc('[name="foo@bar.org"]').attr("checked")
|
||||
delivery.orders["foo@bar.org"] = Order(
|
||||
products={"123": ProductOrder(wanted=2)}, paid=True
|
||||
)
|
||||
delivery.persist()
|
||||
resp = await client.get(f"/livraison/{delivery.id}/soldes")
|
||||
doc = pq(resp.body)
|
||||
assert doc('[name="foo@bar.org"]').attr("checked")
|
||||
|
||||
|
||||
async def test_post_delivery_balance(client, delivery):
|
||||
delivery.order_before = datetime.now() - timedelta(days=1)
|
||||
delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)})
|
||||
delivery.persist()
|
||||
body = {"foo@bar.org": "on"}
|
||||
resp = await client.post(f"/livraison/{delivery.id}/soldes", body=body)
|
||||
assert resp.status == 302
|
||||
delivery = Delivery.load(id=delivery.id)
|
||||
assert delivery.orders["foo@bar.org"].paid is True
|
||||
|
||||
|
||||
async def test_export_products(client, delivery):
|
||||
delivery.persist()
|
||||
resp = await client.get(f"/livraison/{delivery.id}/exporter/produits")
|
||||
|
|
Loading…
Reference in a new issue