Add delivery balance report

This commit is contained in:
Yohan Boniface 2019-04-19 16:47:26 +02:00
parent 434d9f293e
commit 34d6183ad4
8 changed files with 65 additions and 17 deletions

View file

@ -396,7 +396,7 @@ async def adjust_product(request, response, id, ref):
response.html("adjust_product.html", {"delivery": delivery, "product": product}) response.html("adjust_product.html", {"delivery": delivery, "product": product})
@app.route("/livraison/{id}/soldes", methods=["GET", "POST"]) @app.route("/livraison/{id}/solde", methods=["GET", "POST"])
@staff_only @staff_only
async def delivery_balance(request, response, id): async def delivery_balance(request, response, id):
delivery = Delivery.load(id) delivery = Delivery.load(id)
@ -412,6 +412,12 @@ async def delivery_balance(request, response, id):
response.html("delivery_balance.html", {"delivery": delivery}) response.html("delivery_balance.html", {"delivery": delivery})
@app.route("/livraison/{id}/solde.xlsx", methods=["GET"])
async def delivery_balance_report(request, response, id):
delivery = Delivery.load(id)
response.xlsx(reports.balance(delivery))
def configure(): def configure():
config.init() config.init()

View file

@ -68,3 +68,15 @@ def products(delivery):
for product in delivery.products: for product in delivery.products:
ws.append([getattr(product, field) for field in fields]) ws.append([getattr(product, field) for field in fields])
return save_virtual_workbook(wb) return save_virtual_workbook(wb)
def balance(delivery):
wb = Workbook()
ws = wb.active
ws.title = f"Solde {delivery.producer}"
ws.append(["Adhérent", "Montant", "Payé"])
for email, order in delivery.orders.items():
ws.append(
[email, order.total(delivery.products), "oui" if order.paid else "non"]
)
return save_virtual_workbook(wb)

View file

@ -189,10 +189,12 @@ input[type=submit] {
transition: all .2s ease; transition: all .2s ease;
cursor: pointer; cursor: pointer;
} }
input[type=submit] { input[type=submit],
input[type=submit] + a.button {
margin-top: 5px; margin-top: 5px;
} }
input[type=submit]:hover,
.button:hover { .button:hover {
color: #fff; color: #fff;
background-color: var(--primary-color); background-color: var(--primary-color);

View file

@ -91,7 +91,7 @@
</li> </li>
{% if delivery.is_passed %} {% if delivery.is_passed %}
<li> <li>
<a href="/livraison/{{ delivery.id }}/soldes"><i class="icon-wallet"></i> Gérer les soldes</a> <a href="/livraison/{{ delivery.id }}/solde"><i class="icon-wallet"></i> Gérer les soldes</a>
</li> </li>
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -5,16 +5,21 @@
<h3><a href="/livraison/{{ delivery.id }}">{{ delivery.producer }}</a> — Gérer les soldes</h3> <h3><a href="/livraison/{{ delivery.id }}">{{ delivery.producer }}</a> — Gérer les soldes</h3>
<form method="post"> <form method="post">
<table> <table>
<tr><th>Personne</th><th>Montant</th><th>Soldée</th></tr> <thead>
{% for email, order in delivery.orders.items() %} <tr><th>Personne</th><th>Montant</th><th>Soldée</th></tr>
<tr> </thead>
<td>{{ email }}</td> <tbody>
<td>{{ order.total(delivery.products) }} €</td> {% for email, order in delivery.orders.items() %}
<td class="with-input"><input type="checkbox" name="{{ email }}" {% if order.paid %}checked{% endif %}></td> <tr>
</tr> <td>{{ email }}</td>
{% endfor %} <td>{{ order.total(delivery.products) }} €</td>
<td class="with-input"><input type="checkbox" name="{{ email }}" {% if order.paid %}checked{% endif %}></td>
</tr>
{% endfor %}
</tbody>
</table> </table>
<input type="submit" value="Mettre à jour les soldes"> <input type="submit" value="Enregistrer" class="primary">
<a href="/livraison/{{ delivery.id }}/solde.xlsx" class="button"><i class="icon-download"></i>&nbsp;Exporter</a>
</form> </form>
</article> </article>
{% endblock body %} {% endblock body %}

View file

@ -45,7 +45,7 @@
{% endif %} {% endif %}
<input type="hidden" name="email" value="{{ person.email }}"> <input type="hidden" name="email" value="{{ person.email }}">
{% if delivery.status != delivery.CLOSED or request.user.is_staff %} {% if delivery.status != delivery.CLOSED or request.user.is_staff %}
<input type="submit" value="Enregistrer la commande"> <input type="submit" value="Enregistrer la commande" class="primary">
{% endif %} {% endif %}
<a class="button" href="/livraison/{{ delivery.id }}/courriel?email={{ person.email }}">Envoyer par courriel</a> <a class="button" href="/livraison/{{ delivery.id }}/courriel?email={{ person.email }}">Envoyer par courriel</a>
</form> </form>

View file

@ -6,7 +6,7 @@ from copanier import reports
from copanier.models import Order, Product, ProductOrder from copanier.models import Order, Product, ProductOrder
def test_summary_report(client, delivery): def test_summary_report(delivery):
delivery.products[0].packing = 6 delivery.products[0].packing = 6
delivery.products.append( delivery.products.append(
Product(ref="456", name="yaourt", price="3.5", packing=4, unit="pot 125ml") Product(ref="456", name="yaourt", price="3.5", packing=4, unit="pot 125ml")
@ -23,3 +23,26 @@ def test_summary_report(client, delivery):
("456", "yaourt (pot 125ml)", 3.5, 4, "pot 125ml", 14), ("456", "yaourt (pot 125ml)", 3.5, 4, "pot 125ml", 14),
(None, None, None, None, "Total", 15.5), (None, None, None, None, "Total", 15.5),
] ]
def test_balance_report(delivery):
delivery.products = [
Product(ref="123", name="lait", price="1.9", unit="1.5 litre"),
Product(ref="456", name="yaourt", price="3.5", unit="pot 125ml"),
]
delivery.orders = {
"foo@bar.org": Order(
products={"123": ProductOrder(wanted=1), "456": ProductOrder(wanted=4)}
),
"foo@foo.org": Order(
products={"123": ProductOrder(wanted=3), "456": ProductOrder(wanted=2)},
paid=True,
),
}
delivery.persist()
wb = load_workbook(filename=BytesIO(reports.balance(delivery)))
assert list(wb.active.values) == [
("Adhérent", "Montant", "Payé"),
("foo@bar.org", 15.9, "non"),
("foo@foo.org", 12.7, "oui"),
]

View file

@ -212,7 +212,7 @@ async def test_get_delivery_balance(client, delivery):
delivery.from_date = datetime.now() - timedelta(days=1) delivery.from_date = datetime.now() - timedelta(days=1)
delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)}) delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)})
delivery.persist() delivery.persist()
resp = await client.get(f"/livraison/{delivery.id}/soldes") resp = await client.get(f"/livraison/{delivery.id}/solde")
doc = pq(resp.body) doc = pq(resp.body)
assert doc('[name="foo@bar.org"]') assert doc('[name="foo@bar.org"]')
assert not doc('[name="foo@bar.org"]').attr("checked") assert not doc('[name="foo@bar.org"]').attr("checked")
@ -220,7 +220,7 @@ async def test_get_delivery_balance(client, delivery):
products={"123": ProductOrder(wanted=2)}, paid=True products={"123": ProductOrder(wanted=2)}, paid=True
) )
delivery.persist() delivery.persist()
resp = await client.get(f"/livraison/{delivery.id}/soldes") resp = await client.get(f"/livraison/{delivery.id}/solde")
doc = pq(resp.body) doc = pq(resp.body)
assert doc('[name="foo@bar.org"]').attr("checked") assert doc('[name="foo@bar.org"]').attr("checked")
@ -230,7 +230,7 @@ async def test_post_delivery_balance(client, delivery):
delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)}) delivery.orders["foo@bar.org"] = Order(products={"123": ProductOrder(wanted=2)})
delivery.persist() delivery.persist()
body = {"foo@bar.org": "on"} body = {"foo@bar.org": "on"}
resp = await client.post(f"/livraison/{delivery.id}/soldes", body=body) resp = await client.post(f"/livraison/{delivery.id}/solde", body=body)
assert resp.status == 302 assert resp.status == 302
delivery = Delivery.load(id=delivery.id) delivery = Delivery.load(id=delivery.id)
assert delivery.orders["foo@bar.org"].paid is True assert delivery.orders["foo@bar.org"].paid is True