Handle multiple producers per delivery

This commit is contained in:
Alexis Métaireau 2019-04-14 02:18:51 +02:00
parent 04d5fca259
commit 6abe77de05
9 changed files with 80 additions and 16 deletions

View file

@ -37,7 +37,7 @@ def send_order(request, env, person, delivery, order):
env, env,
"order_summary", "order_summary",
person.email, 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, order=order,
delivery=delivery, delivery=delivery,
request=request request=request

View file

@ -24,7 +24,10 @@ def products_from_xlsx(delivery, data):
delivery.products = [] delivery.products = []
for row in rows[1:]: for row in rows[1:]:
raw = {k: v for k, v in dict(zip(headers, row)).items() if v} raw = {k: v for k, v in dict(zip(headers, row)).items() if v}
try:
delivery.products.append(Product(**raw)) delivery.products.append(Product(**raw))
except TypeError as e:
raise ValueError(f"Erreur durant l'importation de {raw['ref']}")
delivery.persist() delivery.persist()

View file

@ -96,6 +96,7 @@ class Product(Base):
url: str = "" url: str = ""
img: str = "" img: str = ""
packing: int = None packing: int = None
producer: str = ""
def __str__(self): def __str__(self):
out = self.name out = self.name
@ -133,9 +134,13 @@ class Order(Base):
yield from self.products.items() yield from self.products.items()
def total(self, products): 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} products = {p.ref: p for p in products}
return round( 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 @property
@ -153,7 +158,7 @@ class Delivery(Base):
ADJUSTMENT = 2 ADJUSTMENT = 2
ARCHIVED = 3 ARCHIVED = 3
producer: str name: str
from_date: datetime_field from_date: datetime_field
to_date: datetime_field to_date: datetime_field
order_before: datetime_field order_before: datetime_field
@ -183,6 +188,10 @@ class Delivery(Base):
def total(self): def total(self):
return round(sum(o.total(self.products) for o in self.orders.values()), 2) 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 @property
def is_open(self): def is_open(self):
return datetime.now().date() <= self.order_before.date() return datetime.now().date() <= self.order_before.date()
@ -288,3 +297,12 @@ class Delivery(Base):
def has_order(self, person): def has_order(self, person):
return person.email in self.orders 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)

View file

@ -41,10 +41,10 @@ def full(delivery):
wb = Workbook() wb = Workbook()
ws = wb.active ws = wb.active
ws.title = f"{delivery.producer} {delivery.from_date.date()}" 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) ws.append(headers)
for product in delivery.products: 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(): for order in delivery.orders.values():
wanted = order.products.get(product.ref) wanted = order.products.get(product.ref)
row.append(wanted.quantity if wanted else 0) row.append(wanted.quantity if wanted else 0)

View file

@ -350,6 +350,7 @@ td.total,
th.total { th.total {
background-color: #bbb; background-color: #bbb;
} }
tr:nth-child(even) { tr:nth-child(even) {
background-color: #ddd; background-color: #ddd;
} }
@ -362,6 +363,15 @@ thead tr * {
thead th + th { thead th + th {
border-left: 1px solid white; border-left: 1px solid white;
} }
tr .producer {
border-bottom: 1px solid #aaa;
}
tr.subtotal {
background-color: #bbb;
}
article.order { article.order {
max-width: 1200px; max-width: 1200px;
margin-left: auto; margin-left: auto;

View file

@ -7,6 +7,9 @@
<table class="delivery"> <table class="delivery">
<thead> <thead>
<tr> <tr>
{% if delivery.has_multiple_producers %}
<th class="producer">Producteur</th>
{% endif %}
<th class="product">Produit</th> <th class="product">Produit</th>
<th class="price">Prix</th> <th class="price">Prix</th>
{% if delivery.has_packing %} {% if delivery.has_packing %}
@ -27,6 +30,9 @@
<tbody> <tbody>
{% for product in delivery.products %} {% for product in delivery.products %}
<tr> <tr>
{% if delivery.has_multiple_producers and (loop.first or loop.previtem.producer != product.producer) %}
<th class="producer" rowspan="{{ delivery.get_products_by(product.producer) | length }}">{{ product.producer }}</th>
{% endif %}
<th class="product">{{ product }}</th> <th class="product">{{ product }}</th>
<td>{{ product.price | round(2) }} €</td> <td>{{ product.price | round(2) }} €</td>
{% if delivery.has_packing %} {% if delivery.has_packing %}
@ -42,15 +48,32 @@
<td title="Commandé: {{ order[product.ref].wanted }} — Ajusté: {{ "%+d"|format(order[product.ref].adjustment) }}">{{ order[product.ref].quantity or "—" }}</td> <td title="Commandé: {{ order[product.ref].wanted }} — Ajusté: {{ "%+d"|format(order[product.ref].adjustment) }}">{{ order[product.ref].quantity or "—" }}</td>
{% endfor %} {% endfor %}
</tr> </tr>
{% if delivery.has_multiple_producers and (loop.last or loop.nextitem.producer != product.producer) %}
<tr class="subtotal">
<td></td>
<th>Sous Total {{ product.producer }}</th>
<td></td>
{% if delivery.has_packing %}
<td></td>
{% endif %}
<th>{{ delivery.total_for_producer(product.producer) }} €</th>
{% for email in delivery.orders.keys() %}
<th>{{ delivery.total_for_producer(product.producer, email) }} €</th>
{% endfor %}
</tr>
{% endif %}
{% endfor %} {% endfor %}
<tr> <tr>
<th class="total"><i class="icon-pricetags"></i> Total</th><td></td> <th class="total"><i class="icon-pricetags"></i> Total</th><td></td>
{% if delivery.has_multiple_producers %}
<td></td>
{% endif %}
{% if delivery.has_packing %} {% if delivery.has_packing %}
<td></td> <td></td>
{% endif %} {% endif %}
<th class="total">{{ delivery.total }} €</th> <th class="total">{{ delivery.total }} €</th>
{% for email, order in delivery.orders.items() %} {% for email, order in delivery.orders.items() %}
<td>{{ order.total(delivery.products) }} €</td> <td class="total">{{ order.total(delivery.products) }} €</td>
{% endfor %} {% endfor %}
</tr> </tr>
</tbody> </tbody>

View file

@ -8,11 +8,11 @@
{% endif %} {% endif %}
<form method="post"> <form method="post">
<label> <label>
<p>Producteur</p> <p>Nom</p>
<input type="text" name="producer" value="{{ delivery.producer or '' }}" required> <input type="text" name="name" value="{{ delivery.name or '' }}">
</label> </label>
<label> <label>
<p>Description des produits</p> <h5>Description des produits</h5>
<input type="text" name="description" value="{{ delivery.description or '' }}"> <input type="text" name="description" value="{{ delivery.description or '' }}">
</label> </label>
<label> <label>

View file

@ -15,6 +15,8 @@
<dd>Prix d'une unité, en euros.</dd> <dd>Prix d'une unité, en euros.</dd>
<dt>unit</dt> <dt>unit</dt>
<dd>Conditionnement d'une unité: 1kg, 33cl…</dd> <dd>Conditionnement d'une unité: 1kg, 33cl…</dd>
<dt>producer</dt>
<dd>Le nom du producteur</dd>
<dt>description</dt> <dt>description</dt>
<dd>Plus de détails sur le produit.</dd> <dd>Plus de détails sur le produit.</dd>
<dt>packing</dt> <dt>packing</dt>

View file

@ -2,30 +2,38 @@
{% block body %} {% block body %}
<article class="order"> <article class="order">
<h3><a href="/livraison/{{ delivery.id }}">{{ delivery.producer }}</a> — Commande de «{{ person.email }}»</h3> <h3>{% if delivery.producer %}<a href="/livraison/{{ delivery.id }}">{{ delivery.producer }}</a>{% endif %}Commande de « {{ person.email }} »</h3>
{% include "includes/delivery_head.html" %} {% include "includes/delivery_head.html" %}
<form method="post"> <form method="post">
<table class="order"> <table class="order">
<thead> <thead>
<tr> <tr>
{% if delivery.has_multiple_producers %}
<th class="producer">Producteur</th>
{% endif %}
<th class="product">Produit</th> <th class="product">Produit</th>
<th class="price">Prix</th> <th class="price">Prix</th>
{% if delivery.has_packing %} {% if delivery.has_packing %}
<th class="packing">Conditionnement</th> <th class="packing">Conditionnement</th>
{% endif %} {% endif %}
<th class="amount">Commande</th> <th class="amount">Commande</th>
{% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments %}<th class="amount">Ajustement +/</th>{% endif %} {% if delivery.status == delivery.ADJUSTMENT or order.has_adjustments %}
<th class="amount">Ajustement +/</th>
{% endif %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for product in delivery.products %} {% for product in delivery.products %}
<tr> <tr>
{% if delivery.has_multiple_producers and (loop.first or loop.previtem.producer != product.producer) %}
<th class="producer" rowspan="{{ delivery.get_products_by(product.producer) | length }}">{{ product.producer }}</th>
{% endif %}
<th class="product">{{ product }} <th class="product">{{ product }}
{% if product.description or product.img %} {% if product.description or product.img %}
{% with unique_id=loop.index %} {% with unique_id=loop.index %}
{% include "includes/modal_product.html" %} {% include "includes/modal_product.html" %}
{% endwith %} {% endwith %}
{% endif %}</p> {% endif %}
</th> </th>
<td>{{ product.price | round(2) }} €</td> <td>{{ product.price | round(2) }} €</td>
{% if delivery.has_packing %} {% if delivery.has_packing %}