Use debts to compute and solve the balances

This commit is contained in:
Alexis M 2019-09-24 21:09:43 +02:00
parent bca36da70c
commit 2e524c92c1
4 changed files with 87 additions and 35 deletions

View file

@ -9,6 +9,9 @@ from roll import Roll, Response, HttpError
from roll.extensions import traceback, simple_server, static
from slugify import slugify
from debts.solver import order_balance, check_balance, reduce_balance
from collections import defaultdict
from functools import partial
from . import config, reports, session, utils, emails, loggers, imports
from .models import Delivery, Order, Person, Product, ProductOrder, Groups, Group
@ -492,6 +495,7 @@ async def import_commande(request, response, id):
response.message(f"Yallah! La commande de {email} a bien été importée !")
response.redirect = f"/livraison/{delivery.id}"
@app.route("/livraison/{id}/importer/commandes", methods=["POST"])
@staff_only
async def import_multiple_commands(request, response, id):
@ -556,20 +560,42 @@ async def adjust_product(request, response, id, ref):
response.html("adjust_product.html", {"delivery": delivery, "product": product})
@app.route("/livraison/{id}/solde", methods=["GET", "POST"])
@app.route("/livraison/{id}/solde", methods=["GET"])
@staff_only
async def delivery_balance(request, response, id):
delivery = Delivery.load(id)
groups = request['groups']
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})
balance = []
for group_id, order in delivery.orders.items():
balance.append((group_id, order.total(delivery.products) * -1))
for producer in delivery.producers.values():
group = groups.get_user_group(producer.referent)
group_id = group.id if group else producer.referent
amount = delivery.total_for_producer(producer.id)
if amount:
balance.append((group_id, amount))
debiters, crediters = order_balance(balance)
check_balance(debiters, crediters)
results = reduce_balance(debiters[:], crediters[:])
results_dict = defaultdict(partial(defaultdict, float))
for debiter, amount, crediter in results:
results_dict[debiter][crediter] = amount
# from pdb import set_trace; set_trace()
response.html("delivery_balance.html", {
"delivery": delivery,
"debiters": debiters,
"crediters": crediters,
"results": results_dict,
"groups": groups.groups,
})
@app.route("/livraison/{id}/solde.xlsx", methods=["GET"])

View file

@ -48,11 +48,9 @@
{% include "includes/modal_copy_emails.html" %}
{% endwith %}
</li>
{% if delivery.is_passed %}
<li>
<a href="/livraison/{{ delivery.id }}/solde"><i class="icon-wallet"></i> Gérer les soldes</a>
<a href="/livraison/{{ delivery.id }}/solde"><i class="icon-wallet"></i> Répartition des paiements</a>
</li>
{% endif %}
{% endif %}
</ul>
{% endblock body %}

View file

@ -1,25 +1,52 @@
{% extends "base.html" %}
{% block head %}
<style media="screen">
table {
font-family:Arial, Helvetica, sans-serif;
color:#666;
font-size:12px;
text-shadow: 1px 1px 0px #fff;
background:#eaebec;
box-shadow: 0 1px 2px #d1d1d1;
}
table tr {
text-align: center;
padding-left:20px;
}
table td:first-child {
text-align: left;
padding-left:20px;
border-left: 0;
}
table td {
padding:5px;
border-top: 1px solid #ffffff;
border-bottom:1px solid #e0e0e0;
border-left: 1px solid #e0e0e0;
background: #fafafa;
}
table tr:hover td {
background: #f2f2f2;
}
</style>
{% endblock head %}
{% block body %}
<article>
<h3><a href="/livraison/{{ delivery.id }}">{{ delivery.producer }}</a> — Gérer les soldes</h3>
<form method="post">
<table>
<thead>
<tr><th>Personne</th><th>Montant</th><th>Soldée</th></tr>
</thead>
<tbody>
{% for email, order in delivery.orders.items() %}
<h1><i class="icon-lightbulb"></i> Répartition des paiements</h1>
<table>
<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>
<td></td>
{% for crediter in crediters %}<td>{% if crediter[0] in groups %} {{ groups[crediter[0]].name }}{% else %}{{ crediter[0] }}{% endif %} (+{{ crediter[1] | round(2) }})</td>{% endfor %}
</tr>
{% for debiter in debiters %}
<tr>
<td>{% if debiter[0] in groups %} {{ groups[debiter[0]].name }}{% else %}{{ debiter[0] }}{% endif %} ({{ debiter[1] | round(2) }})</td>
{% for crediter in crediters %}
{% set due_amount = results[debiter[0]][crediter[0]] | round(2) %}
<td>{% if due_amount != 0.00 %}{{due_amount}}{% endif %}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<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>
</article>
</table>
{% endblock body %}

View file

@ -14,6 +14,7 @@ install_requires =
ujson==1.35
minicli==0.4.4
python-slugify==3.0.2
debts==0.4
[options.extras_require]
dev =