mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +02:00
Add delivery balance report
This commit is contained in:
parent
434d9f293e
commit
34d6183ad4
8 changed files with 65 additions and 17 deletions
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
<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>
|
||||||
|
<thead>
|
||||||
<tr><th>Personne</th><th>Montant</th><th>Soldée</th></tr>
|
<tr><th>Personne</th><th>Montant</th><th>Soldée</th></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
{% for email, order in delivery.orders.items() %}
|
{% for email, order in delivery.orders.items() %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ email }}</td>
|
<td>{{ email }}</td>
|
||||||
|
@ -13,8 +16,10 @@
|
||||||
<td class="with-input"><input type="checkbox" name="{{ email }}" {% if order.paid %}checked{% endif %}></td>
|
<td class="with-input"><input type="checkbox" name="{{ email }}" {% if order.paid %}checked{% endif %}></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% 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> Exporter</a>
|
||||||
</form>
|
</form>
|
||||||
</article>
|
</article>
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"),
|
||||||
|
]
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue