mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +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():
|
for name, field_ in self.__dataclass_fields__.items():
|
||||||
value = getattr(self, name)
|
value = getattr(self, name)
|
||||||
type_ = field_.type
|
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:
|
try:
|
||||||
setattr(self, name, self.cast(type_, value))
|
setattr(self, name, self.cast(type_, value))
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
|
@ -95,6 +96,7 @@ class Product(Base):
|
||||||
description: str = ""
|
description: str = ""
|
||||||
url: str = ""
|
url: str = ""
|
||||||
img: str = ""
|
img: str = ""
|
||||||
|
packing: int = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def label(self):
|
def label(self):
|
||||||
|
@ -159,6 +161,10 @@ class Delivery(Base):
|
||||||
def is_passed(self):
|
def is_passed(self):
|
||||||
return not self.is_foreseen
|
return not self.is_foreseen
|
||||||
|
|
||||||
|
@property
|
||||||
|
def has_packing(self):
|
||||||
|
return any(p.packing for p in self.products)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def init_fs(cls):
|
def init_fs(cls):
|
||||||
cls.get_root().mkdir(parents=True, exist_ok=True)
|
cls.get_root().mkdir(parents=True, exist_ok=True)
|
||||||
|
@ -198,3 +204,10 @@ class Delivery(Base):
|
||||||
if product.ref in order.products:
|
if product.ref in order.products:
|
||||||
total += order.products[product.ref].wanted
|
total += order.products[product.ref].wanted
|
||||||
return total
|
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 {
|
article.delivery th.person {
|
||||||
max-width: 7rem;
|
max-width: 7rem;
|
||||||
}
|
}
|
||||||
|
td.missing,
|
||||||
|
th.missing {
|
||||||
|
background-color: #db7734;
|
||||||
|
}
|
||||||
hr {
|
hr {
|
||||||
background-color: #dbdbdb;
|
background-color: #dbdbdb;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
<th class="ref">Référence</th>
|
<th class="ref">Référence</th>
|
||||||
<th class="product">Produit</th>
|
<th class="product">Produit</th>
|
||||||
<th class="price">Prix</th>
|
<th class="price">Prix</th>
|
||||||
|
{% if delivery.has_packing %}
|
||||||
|
<th class="packing">Lot</th>
|
||||||
|
{% endif %}
|
||||||
<th class="amount">Total</th>
|
<th class="amount">Total</th>
|
||||||
{% for email, order in delivery.orders.items() %}
|
{% for email, order in delivery.orders.items() %}
|
||||||
<th class="person{% if delivery.is_passed and not order.paid %} not-paid{% endif %}">
|
<th class="person{% if delivery.is_passed and not order.paid %} not-paid{% endif %}">
|
||||||
|
@ -26,7 +29,10 @@
|
||||||
<td class="ref">{{ product.ref }}</td>
|
<td class="ref">{{ product.ref }}</td>
|
||||||
<th class="product">{{ product.label }}</th>
|
<th class="product">{{ product.label }}</th>
|
||||||
<td>{{ product.price }} €</td>
|
<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() %}
|
{% for email, order in delivery.orders.items() %}
|
||||||
{% if product.ref in order.products %}
|
{% if product.ref in order.products %}
|
||||||
<td>{{ order.products[product.ref].wanted }}</td>
|
<td>{{ order.products[product.ref].wanted }}</td>
|
||||||
|
@ -37,7 +43,10 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<tr><th class="total"><i class="icon-pricetags"></i> Total</th><td>—</td><td>—</td>
|
<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() %}
|
{% for email, order in delivery.orders.items() %}
|
||||||
<td>{{ order.total(delivery.products) }} €</td>
|
<td>{{ order.total(delivery.products) }} €</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
<dd>Conditionnement d'une unité: 1kg, 33cl…</dd>
|
<dd>Conditionnement d'une unité: 1kg, 33cl…</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>
|
||||||
|
<dd>Contionnement final pour grouper les commandes, le cas échéant, en nombre d'unités.</dd>
|
||||||
<dt>url</dt>
|
<dt>url</dt>
|
||||||
<dd>Une URL éventuelle pointant sur une page présentant le produit.</dd>
|
<dd>Une URL éventuelle pointant sur une page présentant le produit.</dd>
|
||||||
<dt>img</dt>
|
<dt>img</dt>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{% include "includes/delivery_head.html" %}
|
{% include "includes/delivery_head.html" %}
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<table class="order">
|
<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 %}
|
{% for product in delivery.products %}
|
||||||
<tr>
|
<tr>
|
||||||
<th class="product">{{ product.label }}
|
<th class="product">{{ product.label }}
|
||||||
|
@ -16,7 +16,9 @@
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endif %}</p>
|
{% endif %}</p>
|
||||||
</th>
|
</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 %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<p>Total: {{ order.total(delivery.products) if order else 0 }} €</p>
|
<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")
|
resp = await client.get(f"/livraison/{delivery.id}/exporter/produits")
|
||||||
wb = load_workbook(filename=BytesIO(resp.body))
|
wb = load_workbook(filename=BytesIO(resp.body))
|
||||||
assert list(wb.active.values) == [
|
assert list(wb.active.values) == [
|
||||||
("name", "ref", "price", "unit", "description", "url", "img"),
|
("name", "ref", "price", "unit", "description", "url", "img", "packing"),
|
||||||
("Lait", "123", 1.5, None, None, None, None),
|
("Lait", "123", 1.5, None, None, None, None, None),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue