From 6abe77de057f763f844d42676da14f8ccd8f0ca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20M=C3=A9taireau?= Date: Sun, 14 Apr 2019 02:18:51 +0200 Subject: [PATCH] Handle multiple producers per delivery --- copanier/emails.py | 2 +- copanier/imports.py | 5 +++- copanier/models.py | 22 +++++++++++++-- copanier/reports.py | 4 +-- copanier/static/app.css | 10 +++++++ copanier/templates/delivery.html | 27 +++++++++++++++++-- copanier/templates/edit_delivery.html | 6 ++--- .../includes/modal_import_products.html | 2 ++ copanier/templates/place_order.html | 18 +++++++++---- 9 files changed, 80 insertions(+), 16 deletions(-) diff --git a/copanier/emails.py b/copanier/emails.py index 3ab9636..9daf9cd 100644 --- a/copanier/emails.py +++ b/copanier/emails.py @@ -37,7 +37,7 @@ def send_order(request, env, person, delivery, order): env, "order_summary", person.email, - f"{config.SITE_NAME} : résumé de la commande {delivery.producer}", + f"{config.SITE_NAME} : résumé de la commande {delivery.name}", order=order, delivery=delivery, request=request diff --git a/copanier/imports.py b/copanier/imports.py index 1697e3c..802028d 100644 --- a/copanier/imports.py +++ b/copanier/imports.py @@ -24,7 +24,10 @@ def products_from_xlsx(delivery, data): delivery.products = [] for row in rows[1:]: raw = {k: v for k, v in dict(zip(headers, row)).items() if v} - delivery.products.append(Product(**raw)) + try: + delivery.products.append(Product(**raw)) + except TypeError as e: + raise ValueError(f"Erreur durant l'importation de {raw['ref']}") delivery.persist() diff --git a/copanier/models.py b/copanier/models.py index ec6987d..7232ff5 100644 --- a/copanier/models.py +++ b/copanier/models.py @@ -96,6 +96,7 @@ class Product(Base): url: str = "" img: str = "" packing: int = None + producer: str = "" def __str__(self): out = self.name @@ -133,9 +134,13 @@ class Order(Base): yield from self.products.items() def total(self, products): + def _get_price(ref): + product = products.get(ref) + return product.price if product else 0 + products = {p.ref: p for p in products} return round( - sum(p.quantity * products[ref].price for ref, p in self.products.items()), 2 + sum(p.quantity * _get_price(ref) for ref, p in self.products.items()), 2 ) @property @@ -153,7 +158,7 @@ class Delivery(Base): ADJUSTMENT = 2 ARCHIVED = 3 - producer: str + name: str from_date: datetime_field to_date: datetime_field order_before: datetime_field @@ -183,6 +188,10 @@ class Delivery(Base): def total(self): return round(sum(o.total(self.products) for o in self.orders.values()), 2) + @property + def has_multiple_producers(self): + return len(set([p.producer for p in self.products])) > 1 + @property def is_open(self): return datetime.now().date() <= self.order_before.date() @@ -288,3 +297,12 @@ class Delivery(Base): def has_order(self, person): return person.email in self.orders + + def get_products_by(self, producer): + return [p for p in self.products if p.producer == producer] + + def total_for_producer(self, producer, person=None): + 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) diff --git a/copanier/reports.py b/copanier/reports.py index deffd35..2d720f0 100644 --- a/copanier/reports.py +++ b/copanier/reports.py @@ -41,10 +41,10 @@ def full(delivery): wb = Workbook() ws = wb.active ws.title = f"{delivery.producer} {delivery.from_date.date()}" - headers = ["ref", "produit", "prix"] + [e for e in delivery.orders] + ["total"] + headers = ["ref", "produit", "prix", "producer"] + [e for e in delivery.orders] + ["total"] ws.append(headers) for product in delivery.products: - row = [product.ref, str(product), product.price] + row = [product.ref, str(product), product.price, product.producer] for order in delivery.orders.values(): wanted = order.products.get(product.ref) row.append(wanted.quantity if wanted else 0) diff --git a/copanier/static/app.css b/copanier/static/app.css index 94aef00..1d66a02 100644 --- a/copanier/static/app.css +++ b/copanier/static/app.css @@ -350,6 +350,7 @@ td.total, th.total { background-color: #bbb; } + tr:nth-child(even) { background-color: #ddd; } @@ -362,6 +363,15 @@ thead tr * { thead th + th { border-left: 1px solid white; } + +tr .producer { + border-bottom: 1px solid #aaa; +} + +tr.subtotal { + background-color: #bbb; +} + article.order { max-width: 1200px; margin-left: auto; diff --git a/copanier/templates/delivery.html b/copanier/templates/delivery.html index e8e0e77..085a50d 100644 --- a/copanier/templates/delivery.html +++ b/copanier/templates/delivery.html @@ -7,6 +7,9 @@ + {% if delivery.has_multiple_producers %} + + {% endif %} {% if delivery.has_packing %} @@ -27,6 +30,9 @@ {% for product in delivery.products %} + {% if delivery.has_multiple_producers and (loop.first or loop.previtem.producer != product.producer) %} + + {% endif %} {% if delivery.has_packing %} @@ -35,22 +41,39 @@ {{ delivery.product_wanted(product) }} {% if delivery.status == delivery.ADJUSTMENT and delivery.product_missing(product) %} (−{{ delivery.product_missing(product) }}) - {% if request.user.is_staff %}ajuster{% endif %} + {% if request.user.is_staff %}ajuster{% endif %} {% endif %} {% for email, order in delivery.orders.items() %} {% endfor %} + {% if delivery.has_multiple_producers and (loop.last or loop.nextitem.producer != product.producer) %} + + + + + {% if delivery.has_packing %} + + {% endif %} + + {% for email in delivery.orders.keys() %} + + {% endfor %} + + {% endif %} {% endfor %} + {% if delivery.has_multiple_producers %} + + {% endif %} {% if delivery.has_packing %} {% endif %} {% for email, order in delivery.orders.items() %} - + {% endfor %} diff --git a/copanier/templates/edit_delivery.html b/copanier/templates/edit_delivery.html index 2955081..2251b0c 100644 --- a/copanier/templates/edit_delivery.html +++ b/copanier/templates/edit_delivery.html @@ -8,11 +8,11 @@ {% endif %}
ProducteurProduit Prix
{{ product.producer }}{{ product }} {{ product.price | round(2) }} €{{ order[product.ref].quantity or "—" }}
Sous Total {{ product.producer }}{{ delivery.total_for_producer(product.producer) }} €{{ delivery.total_for_producer(product.producer, email) }} €
Total{{ delivery.total }} €{{ order.total(delivery.products) }} €{{ order.total(delivery.products) }} €
+ {% if delivery.has_multiple_producers %} + + {% endif %} {% if delivery.has_packing %} {% endif %} - {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments %}{% endif %} + {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments %} + + {% endif %} {% for product in delivery.products %} + {% if delivery.has_multiple_producers and (loop.first or loop.previtem.producer != product.producer) %} + + {% endif %} {% if delivery.has_packing %} - {{ 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 %} - + {% endif %} {% endfor %}
ProducteurProduit PrixConditionnementCommandeAjustement +/−Ajustement +/−
{{ product.producer }}{{ product }} {% if product.description or product.img %} {% with unique_id=loop.index %} {% include "includes/modal_product.html" %} {% endwith %} - {% endif %}

+ {% endif %}
{{ product.price | round(2) }} €{{ product.packing or "—" }}{% if delivery.status == delivery.ADJUSTMENT and delivery.product_missing(product) %} (−{{ delivery.product_missing(product) }}){% endif %}