From 1f3dd960b08a5f1395ee23130eb0c6aabbacf9a3 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sun, 5 May 2019 17:28:18 +0200 Subject: [PATCH 01/12] Allow to download products of an archived delivery This is how we make a new delivery from an old one. --- copanier/templates/delivery.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/copanier/templates/delivery.html b/copanier/templates/delivery.html index e8e0e77..6a4bf89 100644 --- a/copanier/templates/delivery.html +++ b/copanier/templates/delivery.html @@ -69,9 +69,6 @@ Liste d'émargement {% if request.user and request.user.is_staff %} -
  • - Télécharger les produits -
  • Modifier la livraison
  • @@ -103,5 +100,8 @@ {% endif %} {% endif %} +
  • + Télécharger les produits +
  • {% endblock body %} From e18ad297fa83cb1368d20df9526f16fe54ec3291 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sun, 5 May 2019 17:34:36 +0200 Subject: [PATCH 02/12] Add a dedicated view to download products of archived delivery --- copanier/__init__.py | 6 ++++++ copanier/templates/delivery.html | 9 ++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/copanier/__init__.py b/copanier/__init__.py index 5684d2d..990bc2b 100644 --- a/copanier/__init__.py +++ b/copanier/__init__.py @@ -260,6 +260,12 @@ async def export_products(request, response, id): response.xlsx(reports.products(delivery)) +@app.route("/livraison/archive/{id}/exporter/produits", methods=["GET"]) +async def export_archived_products(request, response, id): + delivery = Delivery.load(f"archive/{id}") + response.xlsx(reports.products(delivery)) + + @app.route("/livraison/{id}/edit", methods=["GET"]) @staff_only async def edit_delivery(request, response, id): diff --git a/copanier/templates/delivery.html b/copanier/templates/delivery.html index 6a4bf89..bd0f07b 100644 --- a/copanier/templates/delivery.html +++ b/copanier/templates/delivery.html @@ -69,6 +69,9 @@ Liste d'émargement {% if request.user and request.user.is_staff %} +
  • + Télécharger les produits +
  • Modifier la livraison
  • @@ -98,10 +101,10 @@
  •  Désarchiver
  • +
  • + Télécharger les produits +
  • {% endif %} {% endif %} -
  • - Télécharger les produits -
  • {% endblock body %} From 049ef6260cf7c4f82e5f93e0d5be86bff20df4e1 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sun, 5 May 2019 17:55:13 +0200 Subject: [PATCH 03/12] Depending on the email client, link may or may not be visible So let's make the link visible --- copanier/templates/emails/access_granted.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/copanier/templates/emails/access_granted.html b/copanier/templates/emails/access_granted.html index 2988fcf..e0807a0 100644 --- a/copanier/templates/emails/access_granted.html +++ b/copanier/templates/emails/access_granted.html @@ -1,5 +1,7 @@

    Hey ho!

    -

    Voici le sésame, clique ici pour t'authentifier.

    +

    Voici le sésame, clique dessus pour t'authentifier, ou copie-colle-le dans ton navigateur:

    + +https://{{ hostname }}/sésame/{{ token }}

    {{ config.EMAIL_SIGNATURE }}

    From 132884385e41c2c425d52da85ffdba1c40bd1efd Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 1 May 2019 17:58:09 +0200 Subject: [PATCH 04/12] Simpler home page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove category titles - we still show first open deliveries, ordered by dead line - passed but non archived delivery status label is "À solder" --- copanier/models.py | 4 +++- copanier/templates/delivery.html | 2 +- copanier/templates/edit_delivery.html | 2 +- copanier/templates/home.html | 4 +--- copanier/templates/includes/delivery_head.html | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/copanier/models.py b/copanier/models.py index ec6987d..8d9a123 100644 --- a/copanier/models.py +++ b/copanier/models.py @@ -239,7 +239,9 @@ class Delivery(Base): @classmethod def incoming(cls): - return [d for d in cls.all() if d.is_foreseen] + return sorted( + [d for d in cls.all() if d.is_foreseen], key=lambda d: d.order_before + ) @classmethod def former(cls): diff --git a/copanier/templates/delivery.html b/copanier/templates/delivery.html index bd0f07b..f2be5fa 100644 --- a/copanier/templates/delivery.html +++ b/copanier/templates/delivery.html @@ -70,7 +70,7 @@ {% if request.user and request.user.is_staff %}
  • - Télécharger les produits + Télécharger les produits
  • Modifier la livraison diff --git a/copanier/templates/edit_delivery.html b/copanier/templates/edit_delivery.html index 2955081..efeb375 100644 --- a/copanier/templates/edit_delivery.html +++ b/copanier/templates/edit_delivery.html @@ -48,7 +48,7 @@
      {% if delivery.status == delivery.CLOSED %}
    • -  Archiver +  Archiver
    • {% endif %}
    • diff --git a/copanier/templates/home.html b/copanier/templates/home.html index d57ebb3..022bcf1 100644 --- a/copanier/templates/home.html +++ b/copanier/templates/home.html @@ -1,12 +1,10 @@ {% extends "base.html" %} {% block body %} -

      Livraisons à venir

      {% with deliveries=incoming %} {% include "includes/delivery_list.html" %} {% endwith %} -

      Livraisons passées

      {% with deliveries=former %} {% include "includes/delivery_list.html" %} {% endwith %} - Voir les livraisons archivées + Voir les livraisons archivées {% endblock body %} diff --git a/copanier/templates/includes/delivery_head.html b/copanier/templates/includes/delivery_head.html index 0e9c9af..c982934 100644 --- a/copanier/templates/includes/delivery_head.html +++ b/copanier/templates/includes/delivery_head.html @@ -3,7 +3,7 @@
    • Lieu {{ delivery.where }}
    • Référent {{ delivery.contact }}
    • Date de livraison
    • -
    • {% if delivery.status == delivery.OPEN %}Date limite de commande {% elif delivery.status == delivery.ADJUSTMENT %}Ajustement en cours{% elif delivery.status == delivery.CLOSED %}Fermée{% else %}Archivée{% endif %}
    • +
    • {% if delivery.status == delivery.OPEN %}Date limite de commande {% elif delivery.status == delivery.ADJUSTMENT %}Ajustement en cours{% elif delivery.status == delivery.CLOSED %}{% if delivery.is_foreseen %}Fermée{% else %}À solder{% endif %}{% else %}Archivée{% endif %}
    • {% if delivery.instructions %}
    • À savoir {{ delivery.instructions }}
    • {% endif %} {% if delivery.infos_url %}
    • Plus d'infos {{ delivery.infos_url|truncate(20)}}
    • {% endif %}
    From 2aeceeca3ce8ae5f38e964d5325338a3a4d84b07 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Wed, 22 May 2019 15:31:58 +0200 Subject: [PATCH 05/12] Display user order info on home page (total + unpaid) --- copanier/models.py | 5 ++ copanier/static/app.css | 80 ++++++++++--------- .../templates/includes/delivery_head.html | 2 +- copanier/templates/includes/order_button.html | 6 ++ 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/copanier/models.py b/copanier/models.py index 8d9a123..bdb5f36 100644 --- a/copanier/models.py +++ b/copanier/models.py @@ -290,3 +290,8 @@ class Delivery(Base): def has_order(self, person): return person.email in self.orders + + def total_for(self, person): + if person.email not in self.orders: + return 0 + return self.orders[person.email].total(self.products) diff --git a/copanier/static/app.css b/copanier/static/app.css index 94aef00..4c86438 100644 --- a/copanier/static/app.css +++ b/copanier/static/app.css @@ -1,23 +1,14 @@ :root { --primary-color: #0062b7; - --primary-color-light: #e6f0fa; - --secondary-color: #e10055; + --link-color: #00d1b2; --text-color: #414664; - --border-color: #e6e6eb; - --primary-background-color: #fff; - --secondary-background-color: #fafafb; - --disease: #7846af; - --disease-light: #f5ebfa; - --country: #0f8796; - --country-light: #e6f5f5; - --group: #d03800; - --group-light: #fff5eb; - --keyword: #8c5a2d; - --keyword-light: #f5f0eb; - --kind: #cd0073; - --kind-light: #faf0f5; - --ern: #32009b; - --ern-light: #ebebf5; + --light-text-color: #fafafb; + --background-color: #fafafb; + --flag-color: #A87CA0; + --warning-color: #FFA631; + --danger-color: #d9534f; + --neutral-color: #4D8FAC; + --success-color: #0f8796; } @@ -103,7 +94,7 @@ body { font-size: .8rem; font-family: 'Work Sans', sans-serif; text-rendering: optimizeLegibility; - background-color: var(--secondary-background-color); + background-color: var(--background-color); padding: 0; margin: 0; } @@ -113,7 +104,6 @@ h3, h4, h5, legend { - /*margin: 0;*/ color: #444; line-height: 1; font-weight: 300; @@ -125,7 +115,7 @@ h3 { font-size: 1.4rem } h4 { font-size: 1.1rem } a { - color: #00d1b2; + color: var(--link-color); cursor: pointer; text-decoration: none; -webkit-transition: none 86ms ease-out; @@ -165,6 +155,7 @@ main { padding: 1rem; } +.flag, button, a.button, input[type=submit] { @@ -196,7 +187,7 @@ input[type=submit] + a.button { input[type=submit]:hover, .button:hover { - color: #fff; + color: var(--light-text-color); background-color: var(--primary-color); } @@ -204,29 +195,40 @@ input[type=submit]:hover, button.primary, a.button.primary, input[type=submit].primary { - color: #fff; + color: var(--background-color); background: var(--primary-color); } button.primary:hover, a.button.primary:hover, input[type=submit].primary:hover { - background-color: #fff; + background-color: var(--background-color); color: var(--primary-color); } button.danger, a.button.danger, input[type=submit].danger { - color: #d9534f; - border-color: #d9534f; + color: var(--danger-color); + border-color: var(--danger-color); } button.danger:hover, a.button.danger:hover, input[type=submit].danger:hover { - background-color: #d9534f; - color: #fff; + background-color: var(--danger-color); + color: var(--light-text-color); +} +.flag { + border-color: var(--flag-color); + color: var(--light-text-color); + background-color: var(--flag-color); + cursor: help; +} +.flag.warning { + background-color: var(--warning-color); + border-color: var(--warning-color); + font-weight: 600; } @@ -247,10 +249,10 @@ textarea { position: relative; height: 2rem; padding: .4rem .8rem; - color: #50596c; + color: var(--text-color); font-size: .8rem; line-height: 1rem; - background-color: #fff; + background-color: var(--background-color); border: .05rem solid #bbc; box-sizing: border-box; } @@ -354,10 +356,10 @@ tr:nth-child(even) { background-color: #ddd; } thead tr { - background-color: #3498db; + background-color: var(--neutral-color); } thead tr * { - color: #f1f1f1; + color: var(--light-text-color); } thead th + th { border-left: 1px solid white; @@ -387,11 +389,11 @@ article.delivery th.person { } td.missing, th.missing { - background-color: #db7734; + background-color: var(--warning-color); } .missing a { - color: #f1f1f1; - border-color: #f1f1f1; + color: var(--light-text-color); + border-color: var(--light-text-color); height: 1rem; } hr { @@ -427,26 +429,26 @@ hr { vertical-align: middle; } .notification.success { - background-color: #0f8796; + background-color: var(--success-color); } .notification.error { - background-color: #e10055; + background-color: var(--danger-color); } .notification.warning { - background-color: #f9b42d; + background-color: var(--warning-color); } .notification i { font-size: 2rem; } .not-paid { - background-color: #db7734; + background-color: var(--warning-color); } .toggle { display: none; } .toggle-label { cursor: pointer; - color: #00d1b2; + color: var(--link-color); } .toggle-container { display: none; diff --git a/copanier/templates/includes/delivery_head.html b/copanier/templates/includes/delivery_head.html index c982934..d99d478 100644 --- a/copanier/templates/includes/delivery_head.html +++ b/copanier/templates/includes/delivery_head.html @@ -3,7 +3,7 @@
  • Lieu {{ delivery.where }}
  • Référent {{ delivery.contact }}
  • Date de livraison
  • -
  • {% if delivery.status == delivery.OPEN %}Date limite de commande {% elif delivery.status == delivery.ADJUSTMENT %}Ajustement en cours{% elif delivery.status == delivery.CLOSED %}{% if delivery.is_foreseen %}Fermée{% else %}À solder{% endif %}{% else %}Archivée{% endif %}
  • +
  • {% if delivery.status == delivery.OPEN %}Date limite de commande {% elif delivery.status == delivery.ADJUSTMENT %}Ajustement en cours{% elif delivery.status == delivery.CLOSED %}{% if delivery.is_foreseen %}Fermée{% else %}Solde en cours{% endif %}{% else %}Archivée{% endif %}
  • {% if delivery.instructions %}
  • À savoir {{ delivery.instructions }}
  • {% endif %} {% if delivery.infos_url %}
  • Plus d'infos {{ delivery.infos_url|truncate(20)}}
  • {% endif %} diff --git a/copanier/templates/includes/order_button.html b/copanier/templates/includes/order_button.html index bd45f48..b1401d9 100644 --- a/copanier/templates/includes/order_button.html +++ b/copanier/templates/includes/order_button.html @@ -7,3 +7,9 @@ {% endif %} {% endif %} +{% if request.user.email in delivery.orders %} +  {{ delivery.total_for(request.user) }} € + {% if delivery.status == delivery.CLOSED and delivery.is_passed and not delivery.orders[request.user.email].paid %} +  Commande à solder + {% endif %} +{% endif %} From bd2fb3958ea442c0e6557cea8859711b4511c3b9 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sat, 25 May 2019 17:12:52 +0200 Subject: [PATCH 06/12] Allow to force ajustment on closed deliveries This is useful for deliveries with missing products to adjust totals before sending --- copanier/__init__.py | 6 +++++- copanier/static/app.css | 3 ++- copanier/templates/place_order.html | 9 ++++++--- tests/test_views.py | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/copanier/__init__.py b/copanier/__init__.py index 990bc2b..1abb7d6 100644 --- a/copanier/__init__.py +++ b/copanier/__init__.py @@ -346,9 +346,13 @@ async def place_order(request, response, id): response.redirect = f"/livraison/{delivery.id}" else: order = delivery.orders.get(email) or Order() + force_adjustment = "adjust" in request.query and user and user.is_staff response.html( "place_order.html", - {"delivery": delivery, "person": Person(email=email), "order": order}, + delivery=delivery, + person=Person(email=email), + order=order, + force_adjustment=force_adjustment, ) diff --git a/copanier/static/app.css b/copanier/static/app.css index 4c86438..f6b2463 100644 --- a/copanier/static/app.css +++ b/copanier/static/app.css @@ -181,7 +181,8 @@ input[type=submit] { cursor: pointer; } input[type=submit], -input[type=submit] + a.button { +input[type=submit] + a.button, +a.button + a.button { margin-top: 5px; } diff --git a/copanier/templates/place_order.html b/copanier/templates/place_order.html index 8c0d84c..1f7dea7 100644 --- a/copanier/templates/place_order.html +++ b/copanier/templates/place_order.html @@ -14,7 +14,7 @@ Conditionnement {% endif %} Commande - {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments %}Ajustement +/−{% endif %} + {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments or force_adjustment %}Ajustement +/−{% endif %} @@ -32,8 +32,8 @@ {{ product.packing or "—" }}{% if delivery.status == delivery.ADJUSTMENT and delivery.product_missing(product) %} (−{{ delivery.product_missing(product) }}){% endif %} {% endif %} - {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments %} - + {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments or force_adjustment %} + {% endif %} {% endfor %} @@ -48,6 +48,9 @@ {% endif %} Envoyer par courriel + {% if request.user.is_staff and delivery.status == delivery.CLOSED %} + Ajuster + {% endif %} {% endblock body %} diff --git a/tests/test_views.py b/tests/test_views.py index 7604b33..d6c5f3b 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -154,6 +154,21 @@ async def test_get_place_order_with_closed_delivery_but_adjustments(client, deli assert doc('[name="adjustment:123"]') +async def test_get_place_order_with_closed_delivery_but_force(client, delivery): + delivery.order_before = datetime.now() - timedelta(days=1) + delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=1)}) + delivery.persist() + assert delivery.status == delivery.CLOSED + resp = await client.get(f"/livraison/{delivery.id}/commander") + doc = pq(resp.body) + assert doc('[name="wanted:123"]').attr("readonly") is not None + assert not doc('[name="adjustment:123"]') + resp = await client.get(f"/livraison/{delivery.id}/commander?adjust") + doc = pq(resp.body) + assert doc('[name="wanted:123"]').attr("readonly") is not None + assert doc('[name="adjustment:123"]') + + async def test_cannot_place_order_on_closed_delivery(client, delivery, monkeypatch): monkeypatch.setattr("copanier.config.STAFF", ["someone@else.org"]) delivery.order_before = datetime.now() - timedelta(days=1) From b3062fd3853744cbf12ff084eb1b924fdb0cd57d Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sat, 25 May 2019 17:33:20 +0200 Subject: [PATCH 07/12] Allow to remove a product from a delivery with orders Eg. when some products are missing from the real delivery while being ordered. --- copanier/models.py | 7 +++++-- tests/test_models.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/copanier/models.py b/copanier/models.py index bdb5f36..910b23e 100644 --- a/copanier/models.py +++ b/copanier/models.py @@ -134,9 +134,12 @@ class Order(Base): def total(self, products): products = {p.ref: p for p in products} - return round( - sum(p.quantity * products[ref].price for ref, p in self.products.items()), 2 + total = sum( + p.quantity * products[ref].price + for ref, p in self.products.items() + if ref in products ) + return round(total, 2) @property def has_adjustments(self): diff --git a/tests/test_models.py b/tests/test_models.py index 4cc531d..7bae88f 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -105,6 +105,16 @@ def test_order_has_adjustments(): assert order.has_adjustments +def test_order_total(delivery): + delivery.products = [Product(name="Lait", ref="123", price=1.5)] + order = Order() + assert order.total(delivery.products) == 0 + order.products["123"] = ProductOrder(wanted=2) + assert order.total(delivery.products) == 3 + order.products["unknown"] = ProductOrder(wanted=2) + assert order.total(delivery.products) == 3 + + def test_can_persist_delivery(delivery): with pytest.raises(AssertionError): delivery.path From c410a4558fb3ff41c18bbe6bd26a4dbd66ed5d4f Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sat, 25 May 2019 19:16:46 +0200 Subject: [PATCH 08/12] Catch SMTP errors --- copanier/__init__.py | 52 +++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/copanier/__init__.py b/copanier/__init__.py index 1abb7d6..b3ab1e0 100644 --- a/copanier/__init__.py +++ b/copanier/__init__.py @@ -141,15 +141,19 @@ async def sesame(request, response): async def send_sesame(request, response, unprotected=True): email = request.form.get("email") token = utils.create_token(email) - emails.send_from_template( - env, - "access_granted", - email, - f"Sésame {config.SITE_NAME}", - hostname=request.host, - token=token.decode(), - ) - response.message(f"Un sésame vous a été envoyé à l'adresse '{email}'") + try: + emails.send_from_template( + env, + "access_granted", + email, + f"Sésame {config.SITE_NAME}", + hostname=request.host, + token=token.decode(), + ) + except RuntimeError: + response.message("Oops, impossible d'envoyer le courriel…", status="error") + else: + response.message(f"Un sésame vous a été envoyé à l'adresse '{email}'") response.redirect = "/" @@ -339,10 +343,20 @@ async def place_order(request, response, id): delivery.persist() if user and user.email == email: # Only send email if order has been placed by the user itself. - emails.send_order( - request, env, person=Person(email=email), delivery=delivery, order=order - ) - response.message(f"La commande pour «{email}» a bien été prise en compte!") + try: + emails.send_order( + request, + env, + person=Person(email=email), + delivery=delivery, + order=order, + ) + except RuntimeError: + response.message("Impossible d'envoyer le courriel…", status="error") + else: + response.message( + f"La commande pour «{email}» a bien été prise en compte!" + ) response.redirect = f"/livraison/{delivery.id}" else: order = delivery.orders.get(email) or Order() @@ -364,10 +378,14 @@ async def send_order(request, response, id): if not order: response.message(f"Aucune commande pour «{email}»", status="warning") else: - emails.send_order( - request, env, person=Person(email=email), delivery=delivery, order=order - ) - response.message(f"Résumé de commande envoyé à «{email}»") + try: + emails.send_order( + request, env, person=Person(email=email), delivery=delivery, order=order + ) + except RuntimeError: + response.message("Oops, impossible d'envoyer le courriel…", status="error") + else: + response.message(f"Résumé de commande envoyé à «{email}»") response.redirect = f"/livraison/{delivery.id}" From c2c466ce2714ca83b171ff03d7ac4530030de0b6 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sat, 25 May 2019 19:17:41 +0200 Subject: [PATCH 09/12] Add product reference in order summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Useful in post delivery checks (it appears in the liste d'émargement) and it's always better non ambigous which product it is --- copanier/templates/includes/order_summary.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/copanier/templates/includes/order_summary.html b/copanier/templates/includes/order_summary.html index ea3020f..8107dfb 100644 --- a/copanier/templates/includes/order_summary.html +++ b/copanier/templates/includes/order_summary.html @@ -1,10 +1,12 @@ - + {% for product in delivery.products %} {% if order[product].quantity %} + - + + {% endif %} {% endfor %} From 9afe04ccf57fab6f0c2181a99133f3152f86f8dd Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sat, 25 May 2019 19:25:53 +0200 Subject: [PATCH 10/12] Make sure we cannot set an ajustment below what user ordered --- copanier/templates/place_order.html | 2 +- tests/test_views.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/copanier/templates/place_order.html b/copanier/templates/place_order.html index 1f7dea7..84bd26b 100644 --- a/copanier/templates/place_order.html +++ b/copanier/templates/place_order.html @@ -33,7 +33,7 @@ {% endif %} {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments or force_adjustment %} - + {% endif %} {% endfor %} diff --git a/tests/test_views.py b/tests/test_views.py index d6c5f3b..c9a8763 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -131,6 +131,7 @@ async def test_get_place_order_with_adjustment_status(client, delivery): assert doc('[name="wanted:123"]').attr("readonly") assert doc('[name="adjustment:123"]') assert not doc('[name="adjustment:123"]').attr("readonly") + assert doc('[name="adjustment:123"]').attr("min") == "-1" assert doc('[name="wanted:456"]').attr("readonly") assert doc('[name="adjustment:456"]') # Already adjusted. From 28cb3220e1fdb30be174ae69c0ea220a15fcd5d0 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 7 Jun 2019 12:50:33 +0200 Subject: [PATCH 11/12] Allow to control remote HOST for emails --- remote/__main__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/remote/__main__.py b/remote/__main__.py index d1d9d6a..e99d76c 100644 --- a/remote/__main__.py +++ b/remote/__main__.py @@ -184,6 +184,7 @@ def upload_env(): "COPANIER_SEND_EMAILS": "1", "COPANIER_SMTP_PASSWORD": None, "COPANIER_SMTP_LOGIN": None, + "COPANIER_SMTP_HOST": None, "COPANIER_STAFF": None, } content = "" From 5b40b9aac8ef1b8c17a6690f7809a1efd40c616f Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 7 Jun 2019 12:51:21 +0200 Subject: [PATCH 12/12] Split back home page to distinguish between active commands and past ones --- copanier/templates/home.html | 1 + 1 file changed, 1 insertion(+) diff --git a/copanier/templates/home.html b/copanier/templates/home.html index 022bcf1..17fd200 100644 --- a/copanier/templates/home.html +++ b/copanier/templates/home.html @@ -3,6 +3,7 @@ {% with deliveries=incoming %} {% include "includes/delivery_list.html" %} {% endwith %} +

    Commandes à solder

    {% with deliveries=former %} {% include "includes/delivery_list.html" %} {% endwith %}
    ProduitPrix unitaireQuantité
    Réf.ProduitPrix unitaireQuantité
    {{ product.ref }} {{ product }}{{ product.price | round(2) }} €{{ order[product].quantity }}{{ product.price | round(2) }} €{{ order[product].quantity }}