From 815eb9543fc7b36474b01d761945cdd1b7d2c9eb Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sun, 14 Apr 2019 17:10:48 +0200 Subject: [PATCH 1/2] Basic "manage delivery balance" page --- copanier/__init__.py | 41 ++++++++++++++++++++---- copanier/templates/delivery.html | 5 +++ copanier/templates/delivery_balance.html | 19 +++++++++++ tests/test_views.py | 38 ++++++++++++++++++---- 4 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 copanier/templates/delivery_balance.html diff --git a/copanier/__init__.py b/copanier/__init__.py index 2c1f5e1..0594141 100644 --- a/copanier/__init__.py +++ b/copanier/__init__.py @@ -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 dangereux 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() diff --git a/copanier/templates/delivery.html b/copanier/templates/delivery.html index 2ac0e1e..349459b 100644 --- a/copanier/templates/delivery.html +++ b/copanier/templates/delivery.html @@ -89,6 +89,11 @@ {% include "includes/modal_copy_emails.html" %} {% endwith %} + {% if delivery.is_passed %} +
  • + Gérer les soldes +
  • + {% endif %} {% endif %} {% endblock body %} diff --git a/copanier/templates/delivery_balance.html b/copanier/templates/delivery_balance.html new file mode 100644 index 0000000..a019bb9 --- /dev/null +++ b/copanier/templates/delivery_balance.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% block body %} +
    +

    {{ delivery.producer }} — Gérer les soldes

    +
    + + + {% for email, order in delivery.orders.items() %} + + + + + {% endfor %} +
    PersonneSoldée
    {{ email }}
    + +
    +
    +{% endblock body %} diff --git a/tests/test_views.py b/tests/test_views.py index aaf0c0d..d211bad 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -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") From bf25a9c7854f25c3dae262548813f65eb8e766d1 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sun, 14 Apr 2019 17:31:07 +0200 Subject: [PATCH 2/2] Add amount in delivery balance page --- copanier/__init__.py | 2 +- copanier/templates/delivery_balance.html | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/copanier/__init__.py b/copanier/__init__.py index 0594141..63db98c 100644 --- a/copanier/__init__.py +++ b/copanier/__init__.py @@ -79,7 +79,7 @@ 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 dangereux par ici", "warning") + 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) diff --git a/copanier/templates/delivery_balance.html b/copanier/templates/delivery_balance.html index a019bb9..dc5011b 100644 --- a/copanier/templates/delivery_balance.html +++ b/copanier/templates/delivery_balance.html @@ -5,10 +5,11 @@

    {{ delivery.producer }} — Gérer les soldes

    - + {% for email, order in delivery.orders.items() %} + {% endfor %}
    PersonneSoldée
    PersonneMontantSoldée
    {{ email }}{{ order.total(delivery.products) }} €