mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 03:22:37 +02:00
Update the demo mode
This commit is contained in:
parent
5e1e88545f
commit
ff262418c3
16 changed files with 789 additions and 711 deletions
|
@ -12,6 +12,10 @@ import yaml
|
||||||
from . import config
|
from . import config
|
||||||
|
|
||||||
|
|
||||||
|
def demo_mode_enabled():
|
||||||
|
return getattr(config, "DEMO_MODE", False)
|
||||||
|
|
||||||
|
|
||||||
class DoesNotExist(ValueError):
|
class DoesNotExist(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -78,13 +82,12 @@ class Base:
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PersistedBase(Base):
|
class PersistedBase(Base):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_root(cls):
|
def get_root(cls):
|
||||||
root = Path(config.DATA_ROOT)
|
root = Path(config.DATA_ROOT)
|
||||||
if getattr(config, 'DEMO_MODE', False):
|
if demo_mode_enabled():
|
||||||
root = root / "demo"
|
root = root / "demo"
|
||||||
|
|
||||||
return root / cls.__root__
|
return root / cls.__root__
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,6 +114,7 @@ class SavedConfiguration(PersistedBase):
|
||||||
data = {}
|
data = {}
|
||||||
return cls(**data)
|
return cls(**data)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Person(Base):
|
class Person(Base):
|
||||||
email: str
|
email: str
|
||||||
|
@ -162,19 +166,18 @@ class Groups(PersistedBase):
|
||||||
data = {"groups": {}}
|
data = {"groups": {}}
|
||||||
groups = cls(**data)
|
groups = cls(**data)
|
||||||
return groups
|
return groups
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_defined(cls):
|
def is_defined(cls):
|
||||||
groups = cls.load()
|
groups = cls.load()
|
||||||
return len(groups.groups) > 0
|
return len(groups.groups) > 0
|
||||||
|
|
||||||
|
|
||||||
def persist(self):
|
def persist(self):
|
||||||
with self.__lock__:
|
with self.__lock__:
|
||||||
self.get_path().write_text(self.dump())
|
self.get_path().write_text(self.dump())
|
||||||
|
|
||||||
def add_group(self, group):
|
def add_group(self, group):
|
||||||
assert group.id not in self.groups, "Un groupe avec ce nom existe déjà."
|
assert group.id not in self.groups, "Un foyer avec ce nom existe déjà."
|
||||||
self.groups[group.id] = group
|
self.groups[group.id] = group
|
||||||
|
|
||||||
def add_user(self, email, group_id):
|
def add_user(self, email, group_id):
|
||||||
|
@ -294,7 +297,9 @@ class Order(Base):
|
||||||
p.quantity * _get_price(ref) for ref, p in self.products.items()
|
p.quantity * _get_price(ref) for ref, p in self.products.items()
|
||||||
)
|
)
|
||||||
|
|
||||||
shipping = self.compute_shipping(delivery, producers, email) if include_shipping else 0
|
shipping = (
|
||||||
|
self.compute_shipping(delivery, producers, email) if include_shipping else 0
|
||||||
|
)
|
||||||
|
|
||||||
return round(total_products + shipping, 2)
|
return round(total_products + shipping, 2)
|
||||||
|
|
||||||
|
@ -354,15 +359,19 @@ class Delivery(PersistedBase):
|
||||||
return self.ADJUSTMENT
|
return self.ADJUSTMENT
|
||||||
if self.is_waiting_products:
|
if self.is_waiting_products:
|
||||||
return self.WAITING_PRODUCTS
|
return self.WAITING_PRODUCTS
|
||||||
|
|
||||||
return self.CLOSED
|
return self.CLOSED
|
||||||
|
|
||||||
def products_need_price_update(self, products=None):
|
def products_need_price_update(self, products=None):
|
||||||
products = products or self.products
|
products = products or self.products
|
||||||
max_age = self.from_date.date() - timedelta(days=60)
|
max_age = self.from_date.date() - timedelta(days=60)
|
||||||
return any([product.last_update.date() < max_age
|
return any(
|
||||||
for product in products
|
[
|
||||||
if product.producer in self.producers])
|
product.last_update.date() < max_age
|
||||||
|
for product in products
|
||||||
|
if product.producer in self.producers
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dates(self):
|
def dates(self):
|
||||||
|
@ -373,7 +382,7 @@ class Delivery(PersistedBase):
|
||||||
"price_update_deadline": self.order_before - timedelta(weeks=2),
|
"price_update_deadline": self.order_before - timedelta(weeks=2),
|
||||||
"order_before": self.order_before,
|
"order_before": self.order_before,
|
||||||
"adjustment_deadline": self.order_before + timedelta(days=4),
|
"adjustment_deadline": self.order_before + timedelta(days=4),
|
||||||
"delivery_date": delivery_date
|
"delivery_date": delivery_date,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -387,16 +396,14 @@ class Delivery(PersistedBase):
|
||||||
@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()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_waiting_products(self):
|
def is_waiting_products(self):
|
||||||
return (
|
return (
|
||||||
datetime.now().date() >= self.order_before.date()
|
datetime.now().date() >= self.order_before.date()
|
||||||
and
|
and datetime.now().date() <= self.from_date.date()
|
||||||
datetime.now().date() <= self.from_date.date()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_foreseen(self):
|
def is_foreseen(self):
|
||||||
return datetime.now().date() <= self.from_date.date()
|
return datetime.now().date() <= self.from_date.date()
|
||||||
|
@ -429,49 +436,58 @@ class Delivery(PersistedBase):
|
||||||
|
|
||||||
def _dedupe_products(raw_data):
|
def _dedupe_products(raw_data):
|
||||||
"""On some rare occasions, different products get
|
"""On some rare occasions, different products get
|
||||||
the same identifier (ref).
|
the same identifier (ref).
|
||||||
|
|
||||||
This function finds them and appends "-dedupe" to it.
|
This function finds them and appends "-dedupe" to it.
|
||||||
This is not ideal but fixes the problem before it causes more
|
This is not ideal but fixes the problem before it causes more
|
||||||
trouble (such as https://github.com/spiral-project/copanier/issues/136)
|
trouble (such as https://github.com/spiral-project/copanier/issues/136)
|
||||||
|
|
||||||
This function returns True if dupes have been found.
|
This function returns True if dupes have been found.
|
||||||
"""
|
"""
|
||||||
if ('products' not in raw_data) or len(raw_data['products']) < 1:
|
if ("products" not in raw_data) or len(raw_data["products"]) < 1:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
products = raw_data['products']
|
|
||||||
|
|
||||||
counter = Counter([p['ref'] for p in products])
|
products = raw_data["products"]
|
||||||
|
|
||||||
|
counter = Counter([p["ref"] for p in products])
|
||||||
most_common = counter.most_common(1)[0]
|
most_common = counter.most_common(1)[0]
|
||||||
number_of_dupes = most_common[1]
|
number_of_dupes = most_common[1]
|
||||||
|
|
||||||
if number_of_dupes < 2:
|
if number_of_dupes < 2:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
dupe_id = most_common[0]
|
dupe_id = most_common[0]
|
||||||
# Reconstruct the products list but change the duplicated ID.
|
# Reconstruct the products list but change the duplicated ID.
|
||||||
counter = 0
|
counter = 0
|
||||||
new_products = []
|
new_products = []
|
||||||
for product in products:
|
for product in products:
|
||||||
ref = product['ref']
|
ref = product["ref"]
|
||||||
if ref == dupe_id:
|
if ref == dupe_id:
|
||||||
counter = counter + 1
|
counter = counter + 1
|
||||||
if counter == number_of_dupes: # Only change the last occurence.
|
if counter == number_of_dupes: # Only change the last occurence.
|
||||||
product['ref'] = f'{ref}-dedupe'
|
product["ref"] = f"{ref}-dedupe"
|
||||||
new_products.append(product)
|
new_products.append(product)
|
||||||
raw_data['products'] = new_products
|
raw_data["products"] = new_products
|
||||||
return True
|
return True
|
||||||
|
|
||||||
data = yaml.safe_load(path.read_text())
|
data = yaml.safe_load(path.read_text())
|
||||||
dupe_found = _dedupe_products(data)
|
dupe_found = _dedupe_products(data)
|
||||||
|
|
||||||
# Tolerate extra fields (but we'll lose them if instance is persisted)
|
# Tolerate extra fields (but we'll lose them if instance is persisted)
|
||||||
data = {k: v for k, v in data.items() if k in cls.__dataclass_fields__}
|
data = {k: v for k, v in data.items() if k in cls.__dataclass_fields__}
|
||||||
delivery = cls(**data)
|
delivery = cls(**data)
|
||||||
delivery.id = id
|
delivery.id = id
|
||||||
|
|
||||||
|
if demo_mode_enabled():
|
||||||
|
delivery.from_date = datetime.now()
|
||||||
|
delivery.to_date = datetime.now() + timedelta(days=10)
|
||||||
|
delivery.order_before = datetime.now() + timedelta(days=5)
|
||||||
|
delivery.validate_all_prices()
|
||||||
|
delivery.persist()
|
||||||
|
|
||||||
if dupe_found:
|
if dupe_found:
|
||||||
delivery.persist()
|
delivery.persist()
|
||||||
|
|
||||||
return delivery
|
return delivery
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -480,7 +496,7 @@ class Delivery(PersistedBase):
|
||||||
for path in root.glob("*.yml"):
|
for path in root.glob("*.yml"):
|
||||||
id_ = str(path.relative_to(cls.get_root())).replace(".yml", "")
|
id_ = str(path.relative_to(cls.get_root())).replace(".yml", "")
|
||||||
yield Delivery.load(id_)
|
yield Delivery.load(id_)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_defined(cls):
|
def is_defined(cls):
|
||||||
return len(list(cls.all())) > 0
|
return len(list(cls.all())) > 0
|
||||||
|
@ -591,3 +607,7 @@ class Delivery(PersistedBase):
|
||||||
percentage_person = person_amount / producer_total
|
percentage_person = person_amount / producer_total
|
||||||
shipping = percentage_person * producer_shipping
|
shipping = percentage_person * producer_shipping
|
||||||
return shipping
|
return shipping
|
||||||
|
|
||||||
|
def validate_all_prices(self):
|
||||||
|
for product in self.products:
|
||||||
|
product.last_update = datetime.now()
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
{% if request.user and (request.user.is_staff or not config.HIDE_GROUPS_LINK) %}
|
{% if request.user and (request.user.is_staff or not config.HIDE_GROUPS_LINK) %}
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
<a class="pure-menu-link" class="pure-menu-link" href="{{ url_for('groups') }}"><i
|
<a class="pure-menu-link" class="pure-menu-link" href="{{ url_for('groups') }}"><i
|
||||||
class="icon-globe"></i> Gérer les groupes</a>
|
class="icon-globe"></i> Gérer les foyers</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
|
|
|
@ -9,21 +9,26 @@
|
||||||
<table class="paiements">
|
<table class="paiements">
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
{% for crediter in crediters %}<td>{% if crediter[0] in crediters_groups %} {{ crediters_groups[crediter[0]] }}*{% else %}{{ crediter[0] }}{% endif %} (+{{ crediter[1] | round(2) }})</td>{% endfor %}
|
{% for crediter in crediters %}<td>{% if crediter[0] in crediters_groups %} {{ crediters_groups[crediter[0]]
|
||||||
|
}}*{% else %}{{ crediter[0] }}{% endif %} (+{{ crediter[1] | round(2) }})</td>{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
{% for debiter in debiters %}
|
{% for debiter in debiters %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{% if debiter[0] in debiters_groups %} {{ debiters_groups[debiter[0]].name }}{% else %}{{ debiter[0] }}{% endif %} ({{ debiter[1] | round(2) }})</td>
|
<td>{% if debiter[0] in debiters_groups %} {{ debiters_groups[debiter[0]].name }}{% else %}{{ debiter[0] }}{%
|
||||||
|
endif %} ({{ debiter[1] | round(2) }})</td>
|
||||||
{% for crediter in crediters %}
|
{% for crediter in crediters %}
|
||||||
{% set due_amount = results[debiter[0]][crediter[0]] | round(2) %}
|
{% set due_amount = results[debiter[0]][crediter[0]] | round(2) %}
|
||||||
|
|
||||||
<td>{% if due_amount != 0.00 %}{{due_amount}}{% endif %}</td>
|
<td>{% if due_amount != 0.00 %}{{due_amount}}{% endif %}</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p class="info"><i class="icon-lightbulb"></i> <strong>Mais, comment ça marche ?</strong> La répartition des chèques se fait automatiquement, en soustrayant ce que les personnes doivent (au nom de leur coloc / groupe) à ce qui leur est du (dans le cas où elles sont référentes pour certains produits).</p>
|
<p class="info"><i class="icon-lightbulb"></i> <strong>Mais, comment ça marche ?</strong> La répartition des
|
||||||
<p class="info">Les personnes indiquées avec un <code>*</code> à côté de leur nom sont celles qui ont payé cette commande pour leur groupe.</p>
|
chèques se fait automatiquement, en soustrayant ce que les personnes doivent (au nom de leur foyer) à ce
|
||||||
|
qui leur est du (dans le cas où elles sont référentes pour certains produits).</p>
|
||||||
|
<p class="info">Les personnes indiquées avec un <code>*</code> à côté de leur nom sont celles qui ont payé cette
|
||||||
|
commande pour leur foyer.</p>
|
||||||
|
|
||||||
{% endblock body %}
|
{% endblock body %}
|
|
@ -3,20 +3,26 @@
|
||||||
{% block additional_menu %}
|
{% block additional_menu %}
|
||||||
<div class="pure-menu">
|
<div class="pure-menu">
|
||||||
<ul class="pure-menu-list">
|
<ul class="pure-menu-list">
|
||||||
<li class="pure-menu-item"><a href="{{ url_for('list_products', id=delivery.id) }}/produits.pdf" class="pure-menu-link"><i class="icon-ribbon"></i> Bons de commande</a></li>
|
<li class="pure-menu-item"><a href="{{ url_for('list_products', id=delivery.id) }}/produits.pdf"
|
||||||
<li class="pure-menu-item"><a href="{{ url_for('show_orders_summary', id=delivery.id) }}" class="pure-menu-link"><i class="icon-grid"></i> Commandes groupes</a></li>
|
class="pure-menu-link"><i class="icon-ribbon"></i> Bons de commande</a></li>
|
||||||
<li class="pure-menu-item"><a href="{{ url_for('compute_payments', id=delivery.id) }}" class="pure-menu-link"><i class="icon-wallet"></i> Paiements</a></li>
|
<li class="pure-menu-item"><a href="{{ url_for('show_orders_summary', id=delivery.id) }}"
|
||||||
|
class="pure-menu-link"><i class="icon-grid"></i> Commandes foyers</a></li>
|
||||||
|
<li class="pure-menu-item"><a href="{{ url_for('compute_payments', id=delivery.id) }}" class="pure-menu-link"><i
|
||||||
|
class="icon-wallet"></i> Paiements</a></li>
|
||||||
{% if request['user'].email == delivery.contact and delivery.status > delivery.EMPTY %}
|
{% if request['user'].email == delivery.contact and delivery.status > delivery.EMPTY %}
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
<a class="pure-menu-link" href="{{ url_for('show_delivery_toolbox', id=delivery.id) }}"><i class="icon-tools"></i> Boîte à outils</a>
|
<a class="pure-menu-link" href="{{ url_for('show_delivery_toolbox', id=delivery.id) }}"><i
|
||||||
|
class="icon-tools"></i> Boîte à outils</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if request.user and request.user.is_staff %}
|
{% if request.user and request.user.is_staff %}
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
<a class="pure-menu-link" href="{{ url_for('edit_delivery', id=delivery.id) }}"><i class="icon-adjustments"></i> Modifier la distrib</a>
|
<a class="pure-menu-link" href="{{ url_for('edit_delivery', id=delivery.id) }}"><i
|
||||||
|
class="icon-adjustments"></i> Modifier la distrib</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
<a class="pure-menu-link" href="{{ url_for('list_products', id=delivery.id) }}"><i class="icon-pricetags"></i> Éditer produits</a>
|
<a class="pure-menu-link" href="{{ url_for('list_products', id=delivery.id) }}"><i
|
||||||
|
class="icon-pricetags"></i> Éditer produits</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -25,14 +31,16 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
{% if delivery.status == delivery.CLOSED %}
|
{% if delivery.status == delivery.CLOSED %}
|
||||||
<div class="important-message">Une fois la distribution terminée, reviens ici pour <a class="button" href="{{ url_for('hand_over_delivery', id=delivery.id) }}">passer le relai !</a></div>
|
<div class="important-message">Une fois la distribution terminée, reviens ici pour <a class="button"
|
||||||
|
href="{{ url_for('hand_over_delivery', id=delivery.id) }}">passer le relai !</a></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>{{ delivery.name }}</h1>
|
<h1>{{ delivery.name }}</h1>
|
||||||
<h2>
|
<h2>
|
||||||
Distribution le <i class="icon-clock"></i> {{ delivery.from_date|date }}, {{ delivery.from_date|time }} - {{ delivery.to_date|time }}, à <i class="icon-streetsign"></i> {{ delivery.where }}.
|
Distribution le <i class="icon-clock"></i> {{ delivery.from_date|date }}, {{ delivery.from_date|time }} - {{
|
||||||
|
delivery.to_date|time }}, à <i class="icon-streetsign"></i> {{ delivery.where }}.
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<h3>{% if delivery.products %}
|
<h3>{% if delivery.products %}
|
||||||
|
@ -45,13 +53,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<article class="delivery">
|
<article class="delivery">
|
||||||
{% if request['user'].email == delivery.contact %}
|
{% if request['user'].email == delivery.contact %}
|
||||||
<div class="placeholder center">
|
<div class="placeholder center">
|
||||||
Hey, jettes un coup d'oeil à
|
Hey, jettes un coup d'oeil à
|
||||||
<a href="{{ url_for('show_delivery_toolbox', id=delivery.id) }}"> la boîte à outils</a> !
|
<a href="{{ url_for('show_delivery_toolbox', id=delivery.id) }}"> la boîte à outils</a> !
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if delivery.has_products %}
|
{% if delivery.has_products %}
|
||||||
{% for (id, producer) in delivery.get_producers_for_referent(request.user.email).items() %}
|
{% for (id, producer) in delivery.get_producers_for_referent(request.user.email).items() %}
|
||||||
{% if producer.needs_price_update(delivery) %}
|
{% if producer.needs_price_update(delivery) %}
|
||||||
{% set modal_body %}
|
{% set modal_body %}
|
||||||
|
@ -60,28 +68,32 @@ Hey, jettes un coup d'oeil à
|
||||||
Certains produits dont tu est référent⋅e ont besoin d'être mis à jour.<br /><br />
|
Certains produits dont tu est référent⋅e ont besoin d'être mis à jour.<br /><br />
|
||||||
Est-ce que tu veux t'en occuper maintenant ?<br />
|
Est-ce que tu veux t'en occuper maintenant ?<br />
|
||||||
|
|
||||||
<a class="button" href="{{ url_for('edit_producer', delivery_id=delivery.id, producer_id=producer.id) }}#products">Oui, mettre à jour les prix pour {{ producer.name }}</a>
|
<a class="button"
|
||||||
|
href="{{ url_for('edit_producer', delivery_id=delivery.id, producer_id=producer.id) }}#products">Oui, mettre à
|
||||||
|
jour les prix pour {{ producer.name }}</a>
|
||||||
{%- endset %}
|
{%- endset %}
|
||||||
{{ macros.modal(id="update-price", body=modal_body, checked=True) }}
|
{{ macros.modal(id="update-price", body=modal_body, checked=True) }}
|
||||||
{% break %}
|
{% break %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% include "includes/delivery_table.html" %}
|
{% include "includes/delivery_table.html" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="placeholder">
|
<div class="placeholder">
|
||||||
<h2>😔 Pour le moment, cette distribution est bien vide…</h2>
|
<h2>😔 Pour le moment, cette distribution est bien vide…</h2>
|
||||||
{% if request.user and request.user.is_staff %}
|
{% if request.user and request.user.is_staff %}
|
||||||
Occupons-nous donc de ça ! Deux options :
|
Occupons-nous donc de ça ! Deux options :
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="{{ url_for('create_producer', delivery_id=delivery.id) }}">Ajouter les product⋅eurs⋅rices</a> à la main ;</li>
|
<li><a href="{{ url_for('create_producer', delivery_id=delivery.id) }}">Ajouter les product⋅eurs⋅rices</a> à
|
||||||
<li>Ou bien <a href="{{ url_for('copy_products', id=delivery.id) }}">copier les produits d'une autre distribution</a>.</li>
|
la main ;</li>
|
||||||
|
<li>Ou bien <a href="{{ url_for('copy_products', id=delivery.id) }}">copier les produits d'une autre
|
||||||
|
distribution</a>.</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</article>
|
</article>
|
||||||
<hr>
|
<hr>
|
||||||
<ul class="toolbox">
|
<ul class="toolbox">
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock body %}
|
{% endblock body %}
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block toplink %}<a href="{{ url_for('show_delivery', id=delivery.id) }}">↶ Retourner à la distribution</a>{% endblock %}
|
{% block toplink %}<a href="{{ url_for('show_delivery', id=delivery.id) }}">↶ Retourner à la distribution</a>{% endblock
|
||||||
|
%}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
|
@ -8,7 +9,9 @@
|
||||||
<h1>{{ delivery.name }}</h1>
|
<h1>{{ delivery.name }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<i class="icon-lightbulb"></i> <strong>{{ delivery.orders|length }}</strong> groupes, <strong>{{ delivery.products|length }}</strong> produits et <strong>{{ delivery.producers | length}}</strong> fournisseurs. <br /> Total de la commande : <strong>{{ delivery.total }}€</strong></li>
|
<i class="icon-lightbulb"></i> <strong>{{ delivery.orders|length }}</strong> foyers, <strong>{{ delivery.products|length
|
||||||
|
}}</strong> produits et <strong>{{ delivery.producers | length}}</strong> fournisseurs. <br /> Total de la commande
|
||||||
|
: <strong>{{ delivery.total }}€</strong></li>
|
||||||
|
|
||||||
<h2>Rappel des dates</h2>
|
<h2>Rappel des dates</h2>
|
||||||
{% include "includes/delivery_dates_table.html" %}
|
{% include "includes/delivery_dates_table.html" %}
|
||||||
|
@ -21,23 +24,31 @@
|
||||||
|
|
||||||
Avant et pendant la distribution :
|
Avant et pendant la distribution :
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('groups', id=delivery.id) }}"><i class="icon-globe"></i> Gérer les groupes / colocs</a></li>
|
<li><a href="{{ url_for('groups', id=delivery.id) }}"><i class="icon-globe"></i> Gérer les foyers /
|
||||||
<li><a href="{{ url_for('edit_delivery', id=delivery.id) }}"><i class="icon-pencil"></i> Modifier la commande (dates, lieu, référent⋅e, etc)</a></li>
|
colocs</a></li>
|
||||||
<li><a href="{{ url_for('list_products', id=delivery.id) }}"><i class="icon-pencil"></i> Gérer les produits</a></li>
|
<li><a href="{{ url_for('edit_delivery', id=delivery.id) }}"><i class="icon-pencil"></i> Modifier la commande
|
||||||
|
(dates, lieu, référent⋅e, etc)</a></li>
|
||||||
|
<li><a href="{{ url_for('list_products', id=delivery.id) }}"><i class="icon-pencil"></i> Gérer les
|
||||||
|
produits</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Une fois les commandes passées :
|
Une fois les commandes passées :
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('list_products', id=delivery.id) }}/produits.pdf"><i class="icon-download"></i> Télécharger la liste des produits commandés</a></li>
|
<li><a href="{{ url_for('list_products', id=delivery.id) }}/produits.pdf"><i class="icon-download"></i>
|
||||||
<li><a href="{{ url_for('generate_report', id=delivery.id) }}"><i class="icon-download"></i> Télécharger le tableau des commandes</a></li>
|
Télécharger la liste des produits commandés</a></li>
|
||||||
<li><a href="{{ url_for('send_referent_emails', id=delivery.id) }}"><i class="icon-envelope"></i> Envoyer les infos de commande aux référent⋅e⋅s</a></li>
|
<li><a href="{{ url_for('generate_report', id=delivery.id) }}"><i class="icon-download"></i> Télécharger le
|
||||||
|
tableau des commandes</a></li>
|
||||||
|
<li><a href="{{ url_for('send_referent_emails', id=delivery.id) }}"><i class="icon-envelope"></i> Envoyer les
|
||||||
|
infos de commande aux référent⋅e⋅s</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Pour préparer la distribution :
|
Pour préparer la distribution :
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ url_for('show_orders_summary', id=delivery.id) }}"><i class="icon-document"></i> Fiches de commandes par groupe</a></li>
|
<li><a href="{{ url_for('show_orders_summary', id=delivery.id) }}"><i class="icon-document"></i> Fiches de
|
||||||
<li><a href="{{ url_for('compute_payments', id=delivery.id) }}"><i class="icon-gears"></i> Faire la répartition des paiements</a></li>
|
commandes par foyer</a></li>
|
||||||
|
<li><a href="{{ url_for('compute_payments', id=delivery.id) }}"><i class="icon-gears"></i> Faire la
|
||||||
|
répartition des paiements</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -3,11 +3,11 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="header">
|
<div class="header">
|
||||||
{% if group.id %}
|
{% if group.id %}
|
||||||
<h1>Modifier le groupe</h1>
|
<h1>Modifier le foyer</h1>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Créer un nouveau groupe</h1>
|
<h1>Créer un nouveau foyer</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h4>Les groupes permettent de gérer les commandes pour d'autres personnes (colocs, familles, etc)</h4>
|
<h4>Les foyers permettent de gérer les commandes pour d'autres personnes (colocs, familles, etc)</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
<input type="text" name="name" value="{{ group.name or '' }}" required>
|
<input type="text" name="name" value="{{ group.name or '' }}" required>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<p>Membres du groupe (emails, séparés par des virgules)</p>
|
<p>Membres du foyer (emails, séparés par des virgules)</p>
|
||||||
<input type="text" name="members" value="{{ ', '.join(group.members) if group.members else '' }}">
|
<input type="text" name="members" value="{{ ', '.join(group.members) if group.members else '' }}">
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
|
@ -27,8 +27,9 @@
|
||||||
{% if group.id %}
|
{% if group.id %}
|
||||||
<ul class="toolbox">
|
<ul class="toolbox">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('delete_group', id=group.id) }}" class="button danger"><i class="icon-hazardous"></i> Supprimer ce groupe</a>
|
<a href="{{ url_for('delete_group', id=group.id) }}" class="button danger"><i
|
||||||
|
class="icon-hazardous"></i> Supprimer ce foyer</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock body %}
|
{% endblock body %}
|
|
@ -2,28 +2,31 @@
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>Groupes</h1>
|
<h1>Foyers</h1>
|
||||||
<div class="pure-menu pure-menu-horizontal">
|
<div class="pure-menu pure-menu-horizontal">
|
||||||
<ul class="pure-menu-list">
|
<ul class="pure-menu-list">
|
||||||
<li class="pure-menu-item">
|
<li class="pure-menu-item">
|
||||||
<a class="pure-menu-link" href="{{ url_for('create_group') }}"><i class="icon-globe"></i> Créer un nouveau groupe</a>
|
<a class="pure-menu-link" href="{{ url_for('create_group') }}"><i class="icon-globe"></i> Créer un
|
||||||
|
nouveau foyer</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not request['user'].group_id %}
|
{% if not request['user'].group_id %}
|
||||||
<p>Bienvenue ! Avant de pouvoir commander, peux-tu nous indiquer pour quelle coloc / famille tu vas passer commande ? </p>
|
<p>Bienvenue ! Avant de pouvoir commander, peux-tu nous indiquer pour quel foyer tu vas passer commande ?
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not groups.groups %}
|
{% if not groups.groups %}
|
||||||
<p>On dirait que tu arrive parmis les premier⋅es ! <a class="button" href="{{ url_for('create_group') }}"><i class="icon-globe"></i> Créé un nouveau groupe.</a></p>
|
<p>On dirait que tu arrive parmis les premier⋅es ! <a class="button" href="{{ url_for('create_group') }}"><i
|
||||||
|
class="icon-globe"></i> Créé un nouveau foyer.</a></p>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
<table id="groups" class="pure-table">
|
<table id="groups" class="pure-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Groupe</th>
|
<th>Foyer</th>
|
||||||
<th>Membres</th>
|
<th>Membres</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -39,13 +42,16 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
<td>{% if group.id != request['user'].group_id %}<a class="pure-button" href="{{ url_for('join_group', id=group.id) }}">rejoindre</a>{% endif %} <a class="pure-button" href="{{ url_for('edit_group', id=group.id) }}">éditer</a></td>
|
<td>{% if group.id != request['user'].group_id %}<a class="pure-button"
|
||||||
|
href="{{ url_for('join_group', id=group.id) }}">rejoindre</a>{% endif %} <a class="pure-button"
|
||||||
|
href="{{ url_for('edit_group', id=group.id) }}">éditer</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p>Tu ne fais partie d'aucun des groupes listés ici ? Tu peux <a class="button" href="{{ url_for('create_group') }}"><i class="icon-globe"></i> en créer un nouveau</a></p>
|
<p>Tu ne fais partie d'aucun des foyers listés ici ? Tu peux <a class="button" href="{{ url_for('create_group') }}"><i
|
||||||
|
class="icon-globe"></i> en créer un nouveau</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,26 +1,31 @@
|
||||||
<table class="pure-table fixed-table">
|
<table class="pure-table fixed-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th><th>Dates</th><th>Coord</th><th>Référent⋅e⋅s</th>
|
<th></th>
|
||||||
|
<th>Dates</th>
|
||||||
|
<th>Coord</th>
|
||||||
|
<th>Référent⋅e⋅s</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Création de la distribution</th>
|
<th>Création de la distribution</th>
|
||||||
<td>{{ delivery.dates.creation_date | date}}</td>
|
<td>{{ delivery.dates.creation_date | date}}</td>
|
||||||
<td>Rappeler aux référent⋅e⋅s produit de mettre leurs prix à jour, vérifier que tous les produits sont bien présentes, en ajouter si besoin</td>
|
<td>Rappeler aux référent⋅e⋅s produit de mettre leurs prix à jour, vérifier que tous les produits sont bien
|
||||||
|
présentes, en ajouter si besoin</td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Mise à jour des prix</th>
|
<th>Mise à jour des prix</th>
|
||||||
<td>Du {{ delivery.dates.price_update_start | date }} au {{ delivery.dates.price_update_deadline | date}}</td>
|
<td>Du {{ delivery.dates.price_update_start | date }} au {{ delivery.dates.price_update_deadline | date}}
|
||||||
|
</td>
|
||||||
<td>—</td>
|
<td>—</td>
|
||||||
<td>Les référent⋅e⋅s produit mettent les prix à jour.</td>
|
<td>Les référent⋅e⋅s produit mettent les prix à jour.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Commandes</th>
|
<th>Commandes</th>
|
||||||
<td>Du {{ delivery.dates.price_update_deadline | date }} au {{ delivery.dates.order_before | date }}</td>
|
<td>Du {{ delivery.dates.price_update_deadline | date }} au {{ delivery.dates.order_before | date }}</td>
|
||||||
<td>Envoyer le lien de commande aux groupes</td>
|
<td>Envoyer le lien de commande aux foyers</td>
|
||||||
<td>—</td>
|
<td>—</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -32,26 +37,30 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th>Récup des produits</th>
|
<th>Récup des produits</th>
|
||||||
<td>Du {{ delivery.dates.adjustment_deadline | date }} au {{ delivery.dates.delivery_date | date }}</td>
|
<td>Du {{ delivery.dates.adjustment_deadline | date }} au {{ delivery.dates.delivery_date | date }}</td>
|
||||||
<td><a href="{{ url_for('send_referent_emails', id=delivery.id) }}">Envoyer les infos de commande aux référent⋅e⋅s</a></td>
|
<td><a href="{{ url_for('send_referent_emails', id=delivery.id) }}">Envoyer les infos de commande aux
|
||||||
|
référent⋅e⋅s</a></td>
|
||||||
<td>Transmettre les commandes, <strong>récupérer les produits</strong></td>
|
<td>Transmettre les commandes, <strong>récupérer les produits</strong></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Préparation de la distribution</th>
|
<th>Préparation de la distribution</th>
|
||||||
<td>La veille du {{ delivery.dates.delivery_date | date }}</td>
|
<td>La veille du {{ delivery.dates.delivery_date | date }}</td>
|
||||||
<td><a href="{{ url_for('show_orders_summary', id=delivery.id) }}">Imprimer les bons de commandes par groupe</a></td>
|
<td><a href="{{ url_for('show_orders_summary', id=delivery.id) }}">Imprimer les bons de commandes par
|
||||||
|
foyer</a></td>
|
||||||
<td>—</td>
|
<td>—</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Distribution</th>
|
<th>Distribution</th>
|
||||||
<td>{{ delivery.dates.delivery_date | date }}</td>
|
<td>{{ delivery.dates.delivery_date | date }}</td>
|
||||||
<td>Coordonner la distribution, <a href="{{ url_for('compute_payments', id=delivery.id) }}">faire la répartition des chèques</a></td>
|
<td>Coordonner la distribution, <a href="{{ url_for('compute_payments', id=delivery.id) }}">faire la
|
||||||
|
répartition des chèques</a></td>
|
||||||
<td>Arriver 30mn avant le début de la distribution, répartir les produits par coloc</td>
|
<td>Arriver 30mn avant le début de la distribution, répartir les produits par coloc</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Transmission</th>
|
<th>Transmission</th>
|
||||||
<td>Après la distribution</td>
|
<td>Après la distribution</td>
|
||||||
<td><a href="{{ url_for('hand_over_delivery', id=delivery.id) }}">Passer le relai à la nouvelle personne référente</a></a></td>
|
<td><a href="{{ url_for('hand_over_delivery', id=delivery.id) }}">Passer le relai à la nouvelle personne
|
||||||
|
référente</a></a></td>
|
||||||
<td>—</td>
|
<td>—</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
|
@ -1,13 +1,16 @@
|
||||||
{% if deliveries %}
|
{% if deliveries %}
|
||||||
<ul class="delivery">
|
<ul class="delivery">
|
||||||
{% for delivery in deliveries %}
|
{% for delivery in deliveries %}
|
||||||
<li>
|
<li>
|
||||||
<h3><a href="{{ url_for('show_delivery', id=delivery.id) }}"><i class="icon-hotairballoon"></i> {{ delivery.name }}</a> {% include "includes/order_button.html" %} <a class="button" href="{{ url_for('show_delivery', id=delivery.id) }}">Voir les commandes</a></h3>
|
<h3><a href="{{ url_for('show_delivery', id=delivery.id) }}"><i class="icon-hotairballoon"></i> {{ delivery.name
|
||||||
{% include "includes/delivery_head.html" %}
|
}}</a> {% include "includes/order_button.html" %} <a class="button"
|
||||||
</li>
|
href="{{ url_for('show_delivery', id=delivery.id) }}">Voir les commandes</a></h3>
|
||||||
<hr>
|
{% include "includes/delivery_head.html" %}
|
||||||
{% endfor %}
|
</li>
|
||||||
|
<hr>
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>Il n'y a aucune distribution à venir. Vous pouvez <a href="{{ url_for('new_delivery') }}">en lancer une nouvelle</a> !
|
<p>🤔 Il n'y a aucune distribution à venir. Vous pouvez <a href="{{ url_for('new_delivery') }}">en lancer une
|
||||||
{% endif %}
|
nouvelle</a> !
|
||||||
|
{% endif %}
|
|
@ -4,9 +4,13 @@
|
||||||
<p>On dirait que vous venez de lancer ce logiciel pour la première fois, bienvenue ici 😀.</p>
|
<p>On dirait que vous venez de lancer ce logiciel pour la première fois, bienvenue ici 😀.</p>
|
||||||
<p>Pour commencer, deux options :</p>
|
<p>Pour commencer, deux options :</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href=" {{ url_for('activate_demo') }}">Activer le mode de démonstration</a>, cela va charger des données de démonstration pour que vous puissiez aller jeter un coup d'oeil au fonctionnement du logiciel ;</li>
|
<li><a class="button" href=" {{ url_for('activate_demo') }}">Activer le mode de démonstration</a> pour jeter un coup
|
||||||
<li>Ou alors si vous avez envie de commencer à utiliser le logiciel, vous devez commencer par <a href="{{ url_for('groups') }}">rejoindre un groupe</a> et commencer une distribution.</p></li>
|
d'œil rapidement aux fonctionalités.</li>
|
||||||
|
<li>Sinon, vous pouvez commencer par <a class="button" href="{{ url_for('groups') }}">rejoindre un foyer</a> et
|
||||||
|
commencer une distribution.</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<p>Bon voyage 🙏 !</p>
|
<p>La peinture est encore fraiche, alors si vous avez besoin d'un coup de main, n'hésitez pas à <a
|
||||||
{% endblock body %}
|
href="mailto:alexis@notmyidea.org">m'envoyer un mail</a> ! 🙏</p>
|
||||||
|
{% endblock body %}
|
|
@ -20,7 +20,7 @@ async def join_group(request, response, id):
|
||||||
request["groups"].persist()
|
request["groups"].persist()
|
||||||
redirect = "/" if not request["user"].group_id else "/groupes"
|
redirect = "/" if not request["user"].group_id else "/groupes"
|
||||||
|
|
||||||
response.message(f"Vous avez bien rejoint le groupe « {group.name} »")
|
response.message(f"Vous avez bien rejoint le foyer « {group.name} »")
|
||||||
response.redirect = redirect
|
response.redirect = redirect
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,14 +41,14 @@ async def create_group(request, response):
|
||||||
)
|
)
|
||||||
request["groups"].add_group(group)
|
request["groups"].add_group(group)
|
||||||
request["groups"].persist()
|
request["groups"].persist()
|
||||||
response.message(f"Le groupe {group.name} à bien été créé")
|
response.message(f"Le foyer {group.name} à bien été créé")
|
||||||
response.redirect = "/"
|
response.redirect = "/"
|
||||||
response.html("groups/edit_group.html", group=group)
|
response.html("groups/edit_group.html", group=group)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/groupes/{id}/éditer", methods=["GET", "POST"])
|
@app.route("/groupes/{id}/éditer", methods=["GET", "POST"])
|
||||||
async def edit_group(request, response, id):
|
async def edit_group(request, response, id):
|
||||||
assert id in request["groups"].groups, "Impossible de trouver le groupe"
|
assert id in request["groups"].groups, "Impossible de trouver le foyer"
|
||||||
group = request["groups"].groups[id]
|
group = request["groups"].groups[id]
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form = request.form
|
form = request.form
|
||||||
|
@ -65,8 +65,8 @@ async def edit_group(request, response, id):
|
||||||
|
|
||||||
@app.route("/groupes/{id}/supprimer", methods=["GET"])
|
@app.route("/groupes/{id}/supprimer", methods=["GET"])
|
||||||
async def delete_group(request, response, id):
|
async def delete_group(request, response, id):
|
||||||
assert id in request["groups"].groups, "Impossible de trouver le groupe"
|
assert id in request["groups"].groups, "Impossible de trouver le foyer"
|
||||||
deleted = request["groups"].groups.pop(id)
|
deleted = request["groups"].groups.pop(id)
|
||||||
request["groups"].persist()
|
request["groups"].persist()
|
||||||
response.message(f"Le groupe {deleted.name} à bien été supprimé")
|
response.message(f"Le foyer {deleted.name} à bien été supprimé")
|
||||||
response.redirect = "/groupes"
|
response.redirect = "/groupes"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from .core import app, session, env, url
|
from .core import app, session, env, url
|
||||||
|
|
||||||
from ..models import Groups, Person, SavedConfiguration
|
from ..models import Groups, Person, SavedConfiguration, Delivery
|
||||||
from .. import utils, emails, config
|
from .. import utils, emails, config
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@ async def auth_required(request, response):
|
||||||
|
|
||||||
saved_config = SavedConfiguration.load()
|
saved_config = SavedConfiguration.load()
|
||||||
if saved_config.demo_mode_enabled:
|
if saved_config.demo_mode_enabled:
|
||||||
setattr(config, 'DEMO_MODE', True)
|
setattr(config, "DEMO_MODE", True)
|
||||||
else:
|
else:
|
||||||
setattr(config, 'DEMO_MODE', False)
|
setattr(config, "DEMO_MODE", False)
|
||||||
|
|
||||||
if request.route.payload and not request.route.payload.get("unprotected"):
|
if request.route.payload and not request.route.payload.get("unprotected"):
|
||||||
token = request.cookies.get("token")
|
token = request.cookies.get("token")
|
||||||
|
@ -96,13 +96,16 @@ async def logout(request, response):
|
||||||
async def onboarding(request, response):
|
async def onboarding(request, response):
|
||||||
response.html("onboarding.html")
|
response.html("onboarding.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/premier-lancement/demo", methods=["GET"])
|
@app.route("/premier-lancement/demo", methods=["GET"])
|
||||||
async def activate_demo(request, response):
|
async def activate_demo(request, response):
|
||||||
saved_config = SavedConfiguration.load()
|
saved_config = SavedConfiguration.load()
|
||||||
saved_config.demo_mode_enabled = True
|
saved_config.demo_mode_enabled = True
|
||||||
|
|
||||||
saved_config.persist()
|
saved_config.persist()
|
||||||
response.redirect = "/"
|
response.redirect = "/"
|
||||||
|
|
||||||
|
|
||||||
@app.route("/premier-lancement/demo/désactiver", methods=["GET"])
|
@app.route("/premier-lancement/demo/désactiver", methods=["GET"])
|
||||||
async def desactivate_demo(request, response):
|
async def desactivate_demo(request, response):
|
||||||
saved_config = SavedConfiguration.load()
|
saved_config = SavedConfiguration.load()
|
||||||
|
|
|
@ -134,9 +134,7 @@ async def validate_producer_prices(request, response, delivery_id, producer_id):
|
||||||
@app.route("/produits/{delivery_id}/valider-prix", methods=["GET"])
|
@app.route("/produits/{delivery_id}/valider-prix", methods=["GET"])
|
||||||
async def mark_all_prices_as_ok(request, response, delivery_id):
|
async def mark_all_prices_as_ok(request, response, delivery_id):
|
||||||
delivery = Delivery.load(delivery_id)
|
delivery = Delivery.load(delivery_id)
|
||||||
|
delivery.validate_all_prices()
|
||||||
for product in delivery.products:
|
|
||||||
product.last_update = datetime.now()
|
|
||||||
delivery.persist()
|
delivery.persist()
|
||||||
|
|
||||||
response.message(f"Les prix ont été marqués comme OK pour toute la distribution !")
|
response.message(f"Les prix ont été marqués comme OK pour toute la distribution !")
|
||||||
|
@ -156,8 +154,12 @@ async def create_product(request, response, delivery_id, producer_id):
|
||||||
product.producer = producer_id
|
product.producer = producer_id
|
||||||
form = request.form
|
form = request.form
|
||||||
product.update_from_form(form)
|
product.update_from_form(form)
|
||||||
random_string = "".join(random.choices(string.ascii_lowercase + string.digits, k=8))
|
random_string = "".join(
|
||||||
product.ref = slugify(f"{producer_id}-{product.name}-{product.unit}-{random_string}")
|
random.choices(string.ascii_lowercase + string.digits, k=8)
|
||||||
|
)
|
||||||
|
product.ref = slugify(
|
||||||
|
f"{producer_id}-{product.name}-{product.unit}-{random_string}"
|
||||||
|
)
|
||||||
|
|
||||||
delivery.products.append(product)
|
delivery.products.append(product)
|
||||||
delivery.persist()
|
delivery.persist()
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,64 +5,38 @@ groups:
|
||||||
- gilki@tenhe.ls
|
- gilki@tenhe.ls
|
||||||
- mohu@zab.tj
|
- mohu@zab.tj
|
||||||
- nazhap@opolarti.ly
|
- nazhap@opolarti.ly
|
||||||
|
- youpi@notmyidea.org
|
||||||
name: Permuflard
|
name: Permuflard
|
||||||
john:
|
|
||||||
id: john
|
|
||||||
members:
|
|
||||||
- voige@sida.li
|
|
||||||
name: John
|
|
||||||
pre-du-fond:
|
|
||||||
id: pre-du-fond
|
|
||||||
members:
|
|
||||||
- sakzace@cetbageg.ne
|
|
||||||
- es@worru.cx
|
|
||||||
name: Pré du fond
|
|
||||||
chez-louise:
|
|
||||||
id: chez-louise
|
|
||||||
members:
|
|
||||||
- suznala@iflavra.ch
|
|
||||||
- sihvo@vo.gn
|
|
||||||
name: Chez Louise
|
|
||||||
les-filles-du-bout:
|
|
||||||
id: les-filles-du-bout
|
|
||||||
members:
|
|
||||||
- tecuhmiz@ilmifhaf.edu
|
|
||||||
- pi@hozep.sj
|
|
||||||
name: Les filles du bout
|
|
||||||
chaton:
|
chaton:
|
||||||
id: chaton
|
id: chaton
|
||||||
members:
|
members:
|
||||||
- puet@helzet.ax
|
- puet@helzet.ax
|
||||||
- bi@noto.fm
|
- bi@noto.fm
|
||||||
name: Châton
|
name: Châton
|
||||||
|
chez-louise:
|
||||||
|
id: chez-louise
|
||||||
|
members:
|
||||||
|
- suznala@iflavra.ch
|
||||||
|
- sihvo@vo.gn
|
||||||
|
name: Chez Louise
|
||||||
chez-pascale:
|
chez-pascale:
|
||||||
id: chez-pascale
|
id: chez-pascale
|
||||||
members:
|
members:
|
||||||
- gawumnud@izkep.bb
|
- gawumnud@izkep.bb
|
||||||
name: Chez Pascale
|
name: Chez Pascale
|
||||||
laxe:
|
john:
|
||||||
id: laxe
|
id: john
|
||||||
members:
|
members:
|
||||||
- couv@rujli.lr
|
- voige@sida.li
|
||||||
- casceci@ziceda.mv
|
name: John
|
||||||
name: Laxe
|
la-bas-au-loin:
|
||||||
mouin:
|
id: la-bas-au-loin
|
||||||
id: mouin
|
|
||||||
members:
|
members:
|
||||||
- rop@uznofkoz.za
|
- uwuvenfo@dunam.na
|
||||||
- ga@ma.gb
|
- va@nowuk.th
|
||||||
- fuatogi@bip.sb
|
- ohu@vukuk.vu
|
||||||
- te@itiorapa.gn
|
- ewmu@migo.hm
|
||||||
name: Mouin
|
name: La Bas au loin
|
||||||
le-chauffage:
|
|
||||||
id: le-chauffage
|
|
||||||
members:
|
|
||||||
- jaigo@hevef.gl
|
|
||||||
- du@nozcoze.lt
|
|
||||||
- em@ca.fk
|
|
||||||
- ifegomcic@pi.lt
|
|
||||||
- zow@hanheh.tn
|
|
||||||
name: Le chauffage
|
|
||||||
la-lointaine:
|
la-lointaine:
|
||||||
id: la-lointaine
|
id: la-lointaine
|
||||||
members:
|
members:
|
||||||
|
@ -72,14 +46,6 @@ groups:
|
||||||
- viw@iwfifbe.ua
|
- viw@iwfifbe.ua
|
||||||
- enji@ladbaped.lt
|
- enji@ladbaped.lt
|
||||||
name: La lointaine
|
name: La lointaine
|
||||||
la-bas-au-loin:
|
|
||||||
id: la-bas-au-loin
|
|
||||||
members:
|
|
||||||
- uwuvenfo@dunam.na
|
|
||||||
- va@nowuk.th
|
|
||||||
- ohu@vukuk.vu
|
|
||||||
- ewmu@migo.hm
|
|
||||||
name: La Bas au loin
|
|
||||||
la-lumiere:
|
la-lumiere:
|
||||||
id: la-lumiere
|
id: la-lumiere
|
||||||
members:
|
members:
|
||||||
|
@ -88,6 +54,12 @@ groups:
|
||||||
- uveruopo@gic.org
|
- uveruopo@gic.org
|
||||||
- zimpok@gogav.sy
|
- zimpok@gogav.sy
|
||||||
name: La lumière
|
name: La lumière
|
||||||
|
la-moins:
|
||||||
|
id: la-moins
|
||||||
|
members:
|
||||||
|
- cuud@cof.sc
|
||||||
|
- gavciawu@huzip.ga
|
||||||
|
name: La Moins
|
||||||
la-reclue:
|
la-reclue:
|
||||||
id: la-reclue
|
id: la-reclue
|
||||||
members:
|
members:
|
||||||
|
@ -100,12 +72,21 @@ groups:
|
||||||
- pej@je.pk
|
- pej@je.pk
|
||||||
- fotopesu@sumfu.sm
|
- fotopesu@sumfu.sm
|
||||||
name: la Ville Z
|
name: la Ville Z
|
||||||
la-moins:
|
laxe:
|
||||||
id: la-moins
|
id: laxe
|
||||||
members:
|
members:
|
||||||
- cuud@cof.sc
|
- couv@rujli.lr
|
||||||
- gavciawu@huzip.ga
|
- casceci@ziceda.mv
|
||||||
name: La Moins
|
name: Laxe
|
||||||
|
le-chauffage:
|
||||||
|
id: le-chauffage
|
||||||
|
members:
|
||||||
|
- jaigo@hevef.gl
|
||||||
|
- du@nozcoze.lt
|
||||||
|
- em@ca.fk
|
||||||
|
- ifegomcic@pi.lt
|
||||||
|
- zow@hanheh.tn
|
||||||
|
name: Le chauffage
|
||||||
le-foin:
|
le-foin:
|
||||||
id: le-foin
|
id: le-foin
|
||||||
members:
|
members:
|
||||||
|
@ -126,12 +107,20 @@ groups:
|
||||||
- rocvibuv@nosmijij.tz
|
- rocvibuv@nosmijij.tz
|
||||||
- it@za.rs
|
- it@za.rs
|
||||||
name: Le grand champ
|
name: Le grand champ
|
||||||
ttre:
|
les-filles-du-bout:
|
||||||
id: ttre
|
id: les-filles-du-bout
|
||||||
members:
|
members:
|
||||||
- hutfiro@aje.gov
|
- tecuhmiz@ilmifhaf.edu
|
||||||
- ce@bowzodda.in
|
- pi@hozep.sj
|
||||||
name: TTRE
|
name: Les filles du bout
|
||||||
|
mouin:
|
||||||
|
id: mouin
|
||||||
|
members:
|
||||||
|
- rop@uznofkoz.za
|
||||||
|
- ga@ma.gb
|
||||||
|
- fuatogi@bip.sb
|
||||||
|
- te@itiorapa.gn
|
||||||
|
name: Mouin
|
||||||
passage-creuse:
|
passage-creuse:
|
||||||
id: passage-creuse
|
id: passage-creuse
|
||||||
members:
|
members:
|
||||||
|
@ -153,12 +142,6 @@ groups:
|
||||||
- budavwa@ciwun.mt
|
- budavwa@ciwun.mt
|
||||||
- jisafu@huvogu.jm
|
- jisafu@huvogu.jm
|
||||||
name: Pataudes
|
name: Pataudes
|
||||||
rs:
|
|
||||||
id: rs
|
|
||||||
members:
|
|
||||||
- bok@rebu.de
|
|
||||||
- beko@noza.bz
|
|
||||||
name: R&S
|
|
||||||
peug:
|
peug:
|
||||||
id: peug
|
id: peug
|
||||||
members:
|
members:
|
||||||
|
@ -169,3 +152,21 @@ groups:
|
||||||
- zahpepez@toteppe.hu
|
- zahpepez@toteppe.hu
|
||||||
- fiodvif@fafij.cm
|
- fiodvif@fafij.cm
|
||||||
name: Peug'
|
name: Peug'
|
||||||
|
pre-du-fond:
|
||||||
|
id: pre-du-fond
|
||||||
|
members:
|
||||||
|
- sakzace@cetbageg.ne
|
||||||
|
- es@worru.cx
|
||||||
|
name: Pré du fond
|
||||||
|
rs:
|
||||||
|
id: rs
|
||||||
|
members:
|
||||||
|
- bok@rebu.de
|
||||||
|
- beko@noza.bz
|
||||||
|
name: R&S
|
||||||
|
ttre:
|
||||||
|
id: ttre
|
||||||
|
members:
|
||||||
|
- hutfiro@aje.gov
|
||||||
|
- ce@bowzodda.in
|
||||||
|
name: TTRE
|
||||||
|
|
|
@ -40,7 +40,7 @@ Avant et pendant la distrib :
|
||||||
|
|
||||||
Modifier la commande (dates, lieu, référent⋅e, etc)
|
Modifier la commande (dates, lieu, référent⋅e, etc)
|
||||||
Modifier les produits, les product⋅rices⋅eurs
|
Modifier les produits, les product⋅rices⋅eurs
|
||||||
Gérer les groupes / colocs
|
Gérer les foyers
|
||||||
|
|
||||||
Une fois les commandes passées (après le dimanche 26 janvier)
|
Une fois les commandes passées (après le dimanche 26 janvier)
|
||||||
Télécharger les bons de distribution
|
Télécharger les bons de distribution
|
||||||
|
|
Loading…
Reference in a new issue