Add support for price updates

This commit is contained in:
Alexis MÃtaireau 2020-04-05 19:00:36 +02:00
parent c753036573
commit 55100260d3
6 changed files with 78 additions and 8 deletions

5
TODO
View file

@ -12,8 +12,11 @@ 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
Gérer le souci d'URL pour l'édition d'Apiluly
Rendre le formulaire d'édition producteur plus compact
Ajouter une info « prix mis à jour » pour les référent⋅e⋅s
Gérer les frais de livraison
Rendre plus visible l'action de modifier une commande

View file

@ -1,7 +1,7 @@
import inspect
import threading
import uuid
from datetime import datetime
from datetime import datetime, timedelta
from dataclasses import dataclass, field, asdict
from pathlib import Path
from typing import List, Dict
@ -174,6 +174,10 @@ class Producer(Base):
products = delivery.get_products_by(self.id)
return any([not p.rupture for p in products])
def needs_price_update(self, delivery):
products = delivery.get_products_by(self.id)
return delivery.products_need_price_update(products)
@dataclass
class Product(Base):
@ -258,9 +262,10 @@ class Delivery(PersistedBase):
__lock__ = threading.Lock()
EMPTY = -1
CLOSED = 0
OPEN = 1
ADJUSTMENT = 2
ARCHIVED = 3
NEED_PRICE_UPDATE = 1
OPEN = 2
ADJUSTMENT = 3
ARCHIVED = 4
name: str
from_date: datetime_field
@ -283,12 +288,19 @@ class Delivery(PersistedBase):
return self.EMPTY
if self.is_archived:
return self.ARCHIVED
if self.products_need_price_update():
return self.NEED_PRICE_UPDATE
if self.is_open:
return self.OPEN
if self.needs_adjustment:
return self.ADJUSTMENT
return self.CLOSED
def products_need_price_update(self, products=None):
products = products or self.products
max_age = self.from_date.date() - timedelta(days=60)
return any([product.last_update.date() < max_age for product in products])
@property
def has_products(self):
return len(self.products) > 0

View file

@ -3,7 +3,13 @@
<div class="header">
<h1>{{ delivery.name }}</h1>
<h4>{% if delivery.products %}{% if delivery.status == delivery.OPEN %}Commandes ouvertes jusqu'au {{ delivery.order_before|date }}{% elif delivery.status == delivery.ADJUSTMENT %}Ajustements en cours{% elif delivery.status == delivery.CLOSED %}Fermée{% else %}Archivée{% endif %}{% endif %}.
<h4>{% if delivery.products %}
{% if delivery.status == delivery.OPEN %}Commandes ouvertes jusqu'au {{ delivery.order_before|date }}
{% elif delivery.status == delivery.ADJUSTMENT %}Ajustements en cours
{% elif delivery.status == delivery.CLOSED %}Fermée
{% elif delivery.status == delivery.ARCHIVED %}Archivée
{% elif delivery.status == delivery.NEED_PRICE_UPDATE %}Mise à jour des prix*
{% endif %}{% endif %}
{% include "includes/order_button.html" %}
</h4>
<h4>
@ -46,6 +52,11 @@
<article class="delivery">
{% if delivery.has_products %}
{% for (id, producer) in delivery.get_producers_for_referent(request.user.email).items() %}
{% if producer.needs_price_update(delivery) %}
<p class="notification info">Merci de <a href="/distribution/{{ delivery.id}}/{{ producer.id}}/éditer">mettre à jour les prix pour « {{ producer.name }} ».</a></p>
{% endif %}
{% endfor %}
{% include "includes/delivery_table.html" %}
{% else %}
<div class="placeholder">

View file

@ -6,6 +6,7 @@
{% for producer in producers %}
{% set producer_obj = delivery.producers[producer] %}
<h2>{{ producer_obj.name }}
{% if producer_obj.needs_price_update(delivery) %}*{% endif %}
{% if edit_mode or request.user.is_staff or producer_obj.referent == request.user.email %}
<span class="edit">
<a class="button" href="/distribution/{{ delivery.id }}/{{ producer_obj.id }}/éditer"><i class="icon-ribbon"></i>&nbsp; Gérer ce⋅tte producteur⋅rice</a>

View file

@ -13,19 +13,27 @@
<li class="pure-menu-item">
<a class="pure-menu-link" href="/distribution/{{ delivery.id}}/{{ producer.id }}/supprimer">Supprimer</a>
</li>
{% if producer.needs_price_update(delivery) %}
<li class="pure-menu-item">
<a class="pure-menu-link" href="/distribution/{{ delivery.id}}/{{ producer.id }}/valider-prix">Marquer les prix comme OK</a>
</li>
{% endif %}
</ul>
</div>
{% else %}
<h1>Ajouter un⋅e producteur⋅rice</h1>
{% endif %}
</div>
{% if producer.needs_price_update(delivery) %}
<p class="notification info">Les prix pour {{ producer.name }} ont besoin d'être validés.</p>
{% endif %}
<form method="post">
{% if producer.id %}
<input type="hidden" name="id" value="{{ producer.id }}">
{% else %}
<label>
<p>Nom</p>
<input type="text" name="name" value="{{ producer.name or '' }}">
<input type="text" name="name" value="{{ proneeds_price_updateducer.name or '' }}">
</label>
{% endif %}
<label>
@ -54,7 +62,12 @@
</form>
{% if products %}
<h3>Produits <a class="button" href="/distribution/{{ delivery.id}}/{{ producer.id }}/ajouter-produit">Ajouter un produit</a></h3>
<h3>Produits
<a class="button" href="/distribution/{{ delivery.id}}/{{ producer.id }}/ajouter-produit">Ajouter un produit</a>
{% if producer.needs_price_update(delivery) %}
<a class="button" href="/distribution/{{ delivery.id}}/{{ producer.id }}/valider-prix">Marquer les prix comme OK</a>
{% endif %}
</h3>
<p>Vous pouvez éditer les produits en cliquant sur leur nom.</p>
<table class="pure-table">
<thead>

View file

@ -1,3 +1,5 @@
from datetime import datetime
from slugify import slugify
from .core import app
from ..models import Delivery, Product, Producer
@ -161,6 +163,34 @@ async def edit_product(request, response, delivery_id, producer_id, product_ref)
)
@app.route("/distribution/{delivery_id}/{producer_id}/valider-prix", methods=["GET"])
async def mark_prices_as_ok(request, response, delivery_id, producer_id):
delivery = Delivery.load(delivery_id)
producer = delivery.producers.get(producer_id)
for product in delivery.products:
if product.producer == producer_id:
product.last_update = datetime.now()
delivery.persist()
response.message(
f"Les prix ont été marqués comme OK pour « { producer.name } », merci !"
)
response.redirect = f"/distribution/{delivery_id}/{producer_id}/éditer"
@app.route("/distribution/{delivery_id}/valider-prix", methods=["GET"])
async def mark_prices_as_ok(request, response, delivery_id):
delivery = Delivery.load(delivery_id)
for product in delivery.products:
product.last_update = datetime.now()
delivery.persist()
response.message(f"Les prix ont été marqués comme OK pour toute la distribution !")
response.redirect = f"/distribution/{delivery_id}/produits"
@app.route(
"/distribution/{delivery_id}/{producer_id}/{product_ref}/supprimer", methods=["GET"]
)