diff --git a/TODO b/TODO index 2ef347a..8d74ed8 100644 --- a/TODO +++ b/TODO @@ -10,10 +10,11 @@ x Ajouter un moyen d'ajouter un⋅e producteurice x Ajouter un moyen de changer le nom de la personne référente pour un producteur / productrice x Faciliter la duplication de distribution x Si un produit est en rupture de stock, alors il n'est pas compté dans les totaux -x Permettre la supression des produits x Permettre la suppression de producteurs x Ajouter une info « prix mis à jour » pour les référent⋅e⋅s +Permettre la supression des produits (terminer) + Gérer le souci d'URL pour l'édition d'Apiluly Rendre le formulaire d'édition producteur plus compact diff --git a/copanier/emails.py b/copanier/emails.py index b0f6811..1aac560 100644 --- a/copanier/emails.py +++ b/copanier/emails.py @@ -37,7 +37,7 @@ def send_from_template(env, template, to, subject, **params): send(to, subject, body=txt, html=html) -def send_order(request, env, person, delivery, order): +def send_order(request, env, person, delivery, order, group_id): send_from_template( env, "order_summary", @@ -47,4 +47,5 @@ def send_order(request, env, person, delivery, order): order=order, delivery=delivery, request=request, + group_id=group_id, ) diff --git a/copanier/models.py b/copanier/models.py index 6a2837c..19fc9e5 100644 --- a/copanier/models.py +++ b/copanier/models.py @@ -240,16 +240,25 @@ class Order(Base): def __iter__(self): yield from self.products.items() - def total(self, products): + def total(self, products, delivery, email=None, include_shipping=True): def _get_price(ref): product = products.get(ref) return product.price if product and not product.rupture else 0 + producers = set([p.producer for p in products]) products = {p.ref: p for p in products} - return round( - sum(p.quantity * _get_price(ref) for ref, p in self.products.items()), 2 + + total_products = sum( + p.quantity * _get_price(ref) for ref, p in self.products.items() ) + total_shipping = 0 + if include_shipping: + for producer in producers: + total_shipping = total_shipping + delivery.shipping_for(email, producer) + + return round(total_products + total_shipping, 2) + @property def has_adjustments(self): return any(choice.adjustment for email, choice in self) @@ -277,6 +286,7 @@ class Delivery(PersistedBase): products: List[Product] = field(default_factory=list) producers: Dict[str, Producer] = field(default_factory=dict) orders: Dict[str, Order] = field(default_factory=dict) + shipping: Dict[str, price_field] = field(default_factory=dict) def __post_init__(self): self.id = None # Not a field because we don't want to persist it. @@ -307,7 +317,7 @@ class Delivery(PersistedBase): @property def total(self): - return round(sum(o.total(self.products) for o in self.orders.values()), 2) + return round(sum(o.total(self.products, self) for o in self.orders.values()), 2) @property def is_open(self): @@ -431,11 +441,20 @@ class Delivery(PersistedBase): self.products.remove(product) return product - def total_for_producer(self, producer, person=None): + def total_for_producer(self, producer, person=None, include_shipping=True): producer_products = [p for p in self.products if p.producer == producer] if person: - return self.orders.get(person).total(producer_products) - return round(sum(o.total(producer_products) for o in self.orders.values()), 2) + return self.orders.get(person).total( + producer_products, self, person, include_shipping + ) + return round( + sum( + o.total(producer_products, self, person, include_shipping=False) + for o in self.orders.values() + ) + + self.shipping.get(producer, 0), + 2, + ) def get_producers_for_referent(self, referent): return { @@ -450,4 +469,24 @@ class Delivery(PersistedBase): def total_for(self, person): if person.email not in self.orders: return 0 - return self.orders[person.email].total(self.products) + return self.orders[person.email].total(self.products, self) + + def shipping_for(self, person, producer): + producer_shipping = self.shipping.get(producer) + if not producer_shipping: + return 0 + + if not person: + return producer_shipping + + producer_total = ( + self.total_for_producer(producer, include_shipping=False) + - producer_shipping + ) + person_amount = self.total_for_producer( + producer, person=person, include_shipping=False + ) + + percentage_person = person_amount / producer_total + shipping = percentage_person * producer_shipping + return shipping diff --git a/copanier/templates/delivery/balance.html b/copanier/templates/delivery/balance.html index db9486c..69d8e1b 100644 --- a/copanier/templates/delivery/balance.html +++ b/copanier/templates/delivery/balance.html @@ -1,8 +1,16 @@ {% extends "base.html" %} -{% block title %}
{{ delivery.name }} du {{ delivery.to_date | date }}.
-Les personnes indiquées avec un *
à côté de leur nom sont celles qui ont payé cette commande pour leur groupe.
@@ -13,11 +21,14 @@ | {% if debiter[0] in debiters_groups %} {{ debiters_groups[debiter[0]].name }}{% else %}{{ debiter[0] }}{% endif %} ({{ debiter[1] | round(2) }}) | {% for crediter in crediters %} {% set due_amount = results[debiter[0]][crediter[0]] | round(2) %} - +{% if due_amount != 0.00 %}{{due_amount}}{% endif %} | {% endfor %}
Mais, comment ça marche ? La répartition des chèques se fait automatiquement, en soustrayant ce que les personnes doivent (au nom de leur coloc / groupe) à ce qui leur est du (dans le cas où elles sont référentes pour certains produits).
+Les personnes indiquées avec un *
à côté de leur nom sont celles qui ont payé cette commande pour leur groupe.
Total: {{ order.total(delivery.products) if order else 0 }} €
+Total: {{ order.total(delivery.products, delivery, group_id) if order else 0 }} €
diff --git a/copanier/templates/products/edit_producer.html b/copanier/templates/products/edit_producer.html index 8c4d31f..c516d33 100644 --- a/copanier/templates/products/edit_producer.html +++ b/copanier/templates/products/edit_producer.html @@ -13,6 +13,9 @@