Facilitate the transmission of information at the end of a delivery. (#56)

This is made in order to have moving reponsabilities, and avoid having people taking too much responsability.
This commit is contained in:
Alexis Metaireau 2021-04-10 11:45:21 +02:00 committed by GitHub
parent 1784884a80
commit a06a1590bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 249 additions and 12 deletions

1
.gitignore vendored
View file

@ -7,3 +7,4 @@ venv
.env
.vscode
.pytest_cache
crac.env

View file

@ -20,7 +20,6 @@ SITE_URL = "http://localhost:2244"
SITE_DESCRIPTION = "Shared orders"
EMAIL_SIGNATURE = "The kind people behind copanier"
def init():
for key, value in globals().items():
if key.isupper():

View file

@ -3,7 +3,7 @@ from emails import Message
from . import config
def send(to, subject, body, html=None, copy=None, attachments=None):
def send(to, subject, body, html=None, copy=None, attachments=None, mail_from=None):
if not attachments:
attachments = []
@ -20,6 +20,7 @@ def send(to, subject, body, html=None, copy=None, attachments=None):
message.send(
to=to,
mail_from=mail_from,
smtp={
"host": config.SMTP_HOST,
"user": config.SMTP_LOGIN,
@ -30,11 +31,11 @@ def send(to, subject, body, html=None, copy=None, attachments=None):
)
def send_from_template(env, template, to, subject, **params):
def send_from_template(env, template, to, subject, mail_from=None, **params):
params["config"] = config
html = env.get_template(f"emails/{template}.html").render(**params)
txt = env.get_template(f"emails/{template}.txt").render(**params)
send(to, subject, body=txt, html=html)
send(to, subject, body=txt, html=html, mail_from=mail_from)
def send_order(request, env, person, delivery, order, group_id, **kwargs):

View file

@ -785,3 +785,7 @@ small {
.progressbar li.active + li:after {
background-color: #55b776;
}
#instructions {
height: 100px;
}

View file

@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block toplink %}{% if delivery.id %}<a href="{{ url_for('show_delivery', id=delivery.id) }}">↶ Retourner à la distribution</a>{% endif %}{% endblock %}
{% block body %}
<div>
{% if delivery.id %}
<h1>Passage de la référence (transmission)</h1>
<p>La distribution est maintenant terminée ! Il est temps de passer le relai à une autre personne.</p>
<p>Le plus simple est de remplir les détails pour la prochaine distribution, ainsi que les informations pour les référent·es qui vont évoluer</p>
<p>Et puis on créera la prochaine distribution et on enverra un petit mail à la nouvelle personne référente.</p>
{% endif %}
</div>
<form method="post">
<label>
<p>Nom de la prochaine distribution</p>
<input type="text" name="name" value="{{ delivery.name or '' }}">
</label>
<label>
<p>Email du / de la référent⋅e</p>
<input type="email" name="contact" value="{{ delivery.contact or request.user.email }}" required>
</label>
<label>
<p>Téléphone pour joindre le / la référent⋅e</p>
<input id="contact_phone" onInput="prettifyPhoneNumber('contact_phone')" type="phone" name="contact_phone" value="{{ delivery.contact_phone }}" required>
</label>
<label>
<p>Lieu</p>
<input type="text" name="where" value="{{ delivery.where or '' }}" required>
</label>
<label>
<p>Date de distribution</p>
<input type="date" name="date" value="{{ delivery.from_date.date() if delivery.from_date else '' }}" required> de <input type="time" name="from_time" value="{{ delivery.from_date.time() if delivery.from_date else '' }}" required> à <input type="time" name="to_time" value="{{ delivery.to_date.time() if delivery.to_date else '' }}" required>
</label>
<label>
<p>Date de limite de commande</p>
<input type="date" name="order_before" value="{{ delivery.order_before.date() if delivery.order_before else '' }}" required>
</label>
<label>
<p>Un petit message pour la qui reprend ?</p>
<textarea id="instructions" name="email_body" cols="80" rows="100"></textarea>
</label>
<h2>Emails des référent·es</h2>
<p>Si il y a un changement de référence pour les producteurs·rices, mettez les info à jour :</p>
{% for producer_name, producer in delivery.producers.items() %}
<h3>{{ producer.name }}</h3>
<input name="producer_{{ producer_name }}_referent_name" type="text" value="{{ producer.referent_name }}">
<input name="producer_{{ producer_name }}_referent_email" type="text" value="{{ producer.referent }}">
<input name="producer_{{ producer_name }}_referent_tel" type="text" value="{{ producer.referent_tel }}">
{% endfor %}
<div>
<input type="submit" name="submit" value="Valider" class="primary">
</div>
</form>
<hr>
{% endblock body %}

View file

@ -48,6 +48,8 @@
<div class="placeholder center">
Tu es la personne contact pour l'organisation de cette distribution, merci :-) Pour t'aider, tu peux accéder à
<a href="{{ url_for('show_delivery_toolbox', id=delivery.id) }}"><i class="icon-tools"></i>&nbsp;la boîte à outils</a> !
{% if delivery.status == delivery.CLOSED %}<p>La distribution est maintenant terminée. C'est le moment de <a href="{{ url_for('hand_over_delivery', id=delivery.id) }}">passer le relai, merci !</a></p>{% endif %}
</div>
{% endif %}
{% if delivery.has_products %}

View file

@ -0,0 +1,37 @@
<p>Bonjour,</p>
<p>La personne référente de la dernière distribution vient de la clôturer, et a indiqué que vous étiez la personne référente pour la prochaine distribution.</p>
<p>Bravo :-)</p>
{% if email_body %}
<p>Elle vous a même laissé un petit message : </p>
<p>{{ email_body}}</p>
{% endif %}
<p>Voici les informations renseignées :</p>
<ul>
<li>Nom : {{ delivery.name }}</li>
<li>Date et heure : {{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }}.</li>
<li>Lieu : {{ delivery.location }}</li>
<li>Commandes avant le {{ delivery.order_before|date }}</li>
</ul>
Référent·es produits :
<ul>
</ul>
{% for producer_name, producer in delivery.producers.items() %}
<li>{{ producer.name }} : {{ producer.referent_name }} - <a href="mailto:{{ producer.referent }}">{{ producer.referent }}</a> - <a href="tel:{{ producer.referent_tel }}">{{ producer.referent_tel }}</a></li>
{% endfor %}
<p>Si vous avez besoin de modifier ces informations, vous pouvez le faire <a href="{{ url_for('show_delivery', id=delivery.id) }}">en suivant ce lien.</a></p>
<p>Bonne journée,</p>
<p>{{ config.EMAIL_SIGNATURE }}</p>

View file

@ -0,0 +1,30 @@
Bonjour,
La personne référente de la dernière distribution vient de la clôturer, et a indiqué que vous étiez la personne référente pour la prochaine distribution.
Bravo :-)
{% if email_body %}
Elle vous a même laissé un petit message : {{ email_body }}
{% endif %}
Voici les informations renseignées :
Nom : {{ delivery.name }}
Date et heure : {{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }}.
Lieu : {{ delivery.location }}
Commandes avant le {{ delivery.order_before|date }}.
Référent·es produits :
{% for producer_name, producer in delivery.producers.items() %}
- {{ producer.name }} : {{ producer.referent_name }} - {{ producer.referent }} - {{ producer.referent_tel }}
{% endfor %}
Si vous avez besoin de modifier ces informations, vous pouvez le faire en suivant ce lien :
{{ url_for('show_delivery', id=delivery.id) }}
Bonne journée,
{{ config.EMAIL_SIGNATURE }}

View file

@ -0,0 +1,57 @@
<table class="pure-table fixed-table">
<thead>
<tr>
<th>Quoi ?</th><th>Dates</th><th>Coordinatrice⋅eur</th><th>Référent⋅e⋅s produits</th>
</tr>
</thead>
<tbody>
<tr>
<th>Création de la distribution</th>
<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 producteurs⋅rices sont bien présentes, en ajouter si besoin</td>
<td>-</td>
</tr>
<tr>
<th>Mise à jour des prix</th>
<td>Du {{ delivery.dates.price_update_start | date }} au {{ delivery.dates.price_update_deadline | date}}</td>
<td></td>
<td>Les référent⋅e⋅s produit mettent les prix à jour.</td>
</tr>
<tr>
<th>Commandes</td>
<td>Du {{ delivery.dates.price_update_deadline | date }} au {{ delivery.dates.order_before | date }}</td>
<td>Envoyer le lien de commande aux groupes pour qu'iels commandent</td>
<td></td>
</tr>
<tr>
<th>Ajustements</th>
<td>Du {{ delivery.dates.order_before | date }} au {{ delivery.dates.adjustment_deadline | date }}</td>
<td>S'assurer que les ajustements sont bien faits par les participant⋅e⋅s</td>
<td>Faire les ajustements à la main si besoin</td>
</tr>
<tr>
<th>Approvisionnements</th>
<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>Faire les commandes aux producteurs⋅rices, <strong>récupérer les produits</strong></td>
</tr>
<tr>
<th>Préparation de la distribution</th>
<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 colocation</a></td>
<td></td>
</tr>
<tr>
<th>Distribution</th>
<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>Arriver 30mn avant le début de la distribution, répartir les produits par coloc</td>
</tr>
<tr>
<th>Transmission</th>
<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></td>
</tr>
</tbody>
</table>

View file

@ -14,7 +14,7 @@
</span>
{% endif %}
</h2>
<h5>{% if producer_obj.description %}{{ producer_obj.description }}{% endif %}Référent⋅e : <a href="mailto:{{ producer_obj.referent }}">{{ producer_obj.referent_name }}</a> / {{ producer_obj.referent_tel }}.
<h5>{% if producer_obj.description %}{{ producer_obj.description }}. {% endif %}Référent⋅e : <a href="mailto:{{ producer_obj.referent }}">{{ producer_obj.referent_name }}</a> / {{ producer_obj.referent_tel }}.
{% if not edit_mode and producer_obj.has_rupture_products(delivery) %}
<p><em>Certains produits sont en rupture de stock.</em></p>
{% endif %}

View file

@ -33,22 +33,67 @@ async def home(request, response):
async def new_delivery(request, response):
response.html("delivery/edit_delivery.html", delivery={})
@app.route("/distribution", methods=["POST"])
async def create_delivery(request, response):
form = request.form
def create_delivery_from_form(form):
data = {}
data["from_date"] = f"{form.get('date')} {form.get('from_time')}"
data["to_date"] = f"{form.get('date')} {form.get('to_time')}"
for name in Delivery.__dataclass_fields__.keys():
if name in form:
data[name] = form.get(name)
delivery = Delivery(**data)
return Delivery(**data)
@app.route("/distribution", methods=["POST"])
async def create_delivery(request, response):
delivery = create_delivery_from_form(request.form)
delivery.persist()
response.message("La distribution a bien été créée!")
response.redirect = f"/distribution/{delivery.id}"
@app.route("/distribution/{id}/transmettre", methods=["GET"])
async def hand_over_delivery(request, response, id):
delivery = Delivery.load(id)
response.html(
"delivery/handover_delivery.html",
delivery=delivery,
)
@app.route("/distribution/{id}/transmettre", methods=["POST"])
async def hand_over_delivery_post(request, response, id):
old_delivery = Delivery.load(id)
form = request.form
new_delivery = create_delivery_from_form(form)
new_delivery.producers = old_delivery.producers
new_delivery.products = old_delivery.products
# Update referent fields
for producer_id, producer in new_delivery.producers.items():
producer.referent = form.get(f'producer_{producer_id}_referent_email')
producer.referent_name = form.get(f'producer_{producer_id}_referent_name')
producer.referent_tel = form.get(f'producer_{producer_id}_referent_tel')
new_delivery.producers[producer_id] = producer
new_delivery.persist()
emails.send_from_template(
env,
"handover_delivery",
new_delivery.contact,
f"{config.SITE_NAME} - Passage de flambeau",
old_delivery.contact,
delivery=new_delivery,
email_body = form.get('email_body'),
hostname=request.host,
url_for=app.url_for,
)
response.message("La distribution à bien été créée et le mail envoyé, merci !")
response.redirect = f"/distribution/{new_delivery.id}"
@app.route("/distribution/{id}/{producer}/bon-de-commande.pdf", methods=["GET"])
async def pdf_for_producer(request, response, id, producer):
delivery = Delivery.load(id)