mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 11:32:38 +02:00
WIP: deal with product packing
This commit is contained in:
parent
4b329b7378
commit
165427bf8f
6 changed files with 37 additions and 7 deletions
|
@ -44,7 +44,8 @@ class Base:
|
|||
for name, field_ in self.__dataclass_fields__.items():
|
||||
value = getattr(self, name)
|
||||
type_ = field_.type
|
||||
if not isinstance(value, Base): # Do not recast our classes.
|
||||
# Do not recast our classes.
|
||||
if not isinstance(value, Base) and value is not None:
|
||||
try:
|
||||
setattr(self, name, self.cast(type_, value))
|
||||
except (TypeError, ValueError):
|
||||
|
@ -95,6 +96,7 @@ class Product(Base):
|
|||
description: str = ""
|
||||
url: str = ""
|
||||
img: str = ""
|
||||
packing: int = None
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
|
@ -159,6 +161,10 @@ class Delivery(Base):
|
|||
def is_passed(self):
|
||||
return not self.is_foreseen
|
||||
|
||||
@property
|
||||
def has_packing(self):
|
||||
return any(p.packing for p in self.products)
|
||||
|
||||
@classmethod
|
||||
def init_fs(cls):
|
||||
cls.get_root().mkdir(parents=True, exist_ok=True)
|
||||
|
@ -198,3 +204,10 @@ class Delivery(Base):
|
|||
if product.ref in order.products:
|
||||
total += order.products[product.ref].wanted
|
||||
return total
|
||||
|
||||
def product_missing(self, product):
|
||||
if not product.packing:
|
||||
return 0
|
||||
wanted = self.product_wanted(product)
|
||||
orphan = wanted % product.packing
|
||||
return product.packing - orphan if orphan else 0
|
||||
|
|
|
@ -363,6 +363,10 @@ article.delivery {
|
|||
article.delivery th.person {
|
||||
max-width: 7rem;
|
||||
}
|
||||
td.missing,
|
||||
th.missing {
|
||||
background-color: #db7734;
|
||||
}
|
||||
hr {
|
||||
background-color: #dbdbdb;
|
||||
border: none;
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
<th class="ref">Référence</th>
|
||||
<th class="product">Produit</th>
|
||||
<th class="price">Prix</th>
|
||||
{% if delivery.has_packing %}
|
||||
<th class="packing">Lot</th>
|
||||
{% endif %}
|
||||
<th class="amount">Total</th>
|
||||
{% for email, order in delivery.orders.items() %}
|
||||
<th class="person{% if delivery.is_passed and not order.paid %} not-paid{% endif %}">
|
||||
|
@ -26,7 +29,10 @@
|
|||
<td class="ref">{{ product.ref }}</td>
|
||||
<th class="product">{{ product.label }}</th>
|
||||
<td>{{ product.price }} €</td>
|
||||
<th>{{ delivery.product_wanted(product) }}</th>
|
||||
{% if delivery.has_packing %}
|
||||
<td class="packing">{{ product.packing or '—'}}</td>
|
||||
{% endif %}
|
||||
<th{% if delivery.product_missing(product) %} class="missing" title="Les commandes individuelles ne correspondent pas aux lots"{% endif %}>{{ delivery.product_wanted(product) }}{% if delivery.product_missing(product) %} ({{ delivery.product_missing(product) }}){% endif %}</th>
|
||||
{% for email, order in delivery.orders.items() %}
|
||||
{% if product.ref in order.products %}
|
||||
<td>{{ order.products[product.ref].wanted }}</td>
|
||||
|
@ -37,7 +43,10 @@
|
|||
</tr>
|
||||
{% endfor %}
|
||||
<tr><th class="total"><i class="icon-pricetags"></i> Total</th><td>—</td><td>—</td>
|
||||
<td class="total">{{ delivery.total }} €</td>
|
||||
{% if delivery.has_packing %}
|
||||
<td>—</td>
|
||||
{% endif %}
|
||||
<th class="total">{{ delivery.total }} €</th>
|
||||
{% for email, order in delivery.orders.items() %}
|
||||
<td>{{ order.total(delivery.products) }} €</td>
|
||||
{% endfor %}
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
<dd>Conditionnement d'une unité: 1kg, 33cl…</dd>
|
||||
<dt>description</dt>
|
||||
<dd>Plus de détails sur le produit.</dd>
|
||||
<dt>packing</dt>
|
||||
<dd>Contionnement final pour grouper les commandes, le cas échéant, en nombre d'unités.</dd>
|
||||
<dt>url</dt>
|
||||
<dd>Une URL éventuelle pointant sur une page présentant le produit.</dd>
|
||||
<dt>img</dt>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
{% include "includes/delivery_head.html" %}
|
||||
<form method="post">
|
||||
<table class="order">
|
||||
<tr><th class="product">Produit</th><th class="price">Prix</th><th class="amount">Quantité</th></tr>
|
||||
<tr><th class="product">Produit</th><th class="price">Prix</th><th class="packing">Lot</th><th class="amount">Quantité</th></tr>
|
||||
{% for product in delivery.products %}
|
||||
<tr>
|
||||
<th class="product">{{ product.label }}
|
||||
|
@ -16,7 +16,9 @@
|
|||
{% endwith %}
|
||||
{% endif %}</p>
|
||||
</th>
|
||||
<td>{{ product.price }} €</td><td class="with-input"><input type="number" name="{{ product.ref }}" value="{{ order.get_quantity(product) }}"></td></tr>
|
||||
<td>{{ product.price }} €</td>
|
||||
<td{% if delivery.product_missing(product) %} class="missing" title="Les commandes individuelles ne correspondent pas aux lots"{% endif %}>{{ product.packing or "—" }}{% if delivery.product_missing(product) %} (manque {{ delivery.product_missing(product) }}){% endif %}</td>
|
||||
<td class="with-input"><input type="number" name="{{ product.ref }}" value="{{ order.get_quantity(product) }}"></td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<p>Total: {{ order.total(delivery.products) if order else 0 }} €</p>
|
||||
|
|
|
@ -101,6 +101,6 @@ async def test_export_products(client, delivery):
|
|||
resp = await client.get(f"/livraison/{delivery.id}/exporter/produits")
|
||||
wb = load_workbook(filename=BytesIO(resp.body))
|
||||
assert list(wb.active.values) == [
|
||||
("name", "ref", "price", "unit", "description", "url", "img"),
|
||||
("Lait", "123", 1.5, None, None, None, None),
|
||||
("name", "ref", "price", "unit", "description", "url", "img", "packing"),
|
||||
("Lait", "123", 1.5, None, None, None, None, None),
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue