Generate PDFs rather than XLS files.

Closes #14.
This commit is contained in:
Alexis M 2019-10-05 20:20:13 +02:00
parent 9af506ba4b
commit befb5fd1de
16 changed files with 249 additions and 115 deletions

View file

@ -11,22 +11,48 @@ from roll.extensions import traceback, simple_server, static
from slugify import slugify
from debts.solver import order_balance, check_balance, reduce_balance
from weasyprint import HTML
from . import config, reports, session, utils, emails, loggers, imports
from .models import Delivery, Order, Person, Product, ProductOrder, Groups, Group
class Response(RollResponse):
def html(self, template_name, *args, **kwargs):
self.headers["Content-Type"] = "text/html; charset=utf-8"
def render_template(self, template_name, *args, **kwargs):
context = app.context()
context.update(kwargs)
context["request"] = self.request
context["config"] = config
context["request"] = self.request
if self.request.cookies.get("message"):
context["message"] = json.loads(self.request.cookies["message"])
self.cookies.set("message", "")
context["config"] = config
self.body = env.get_template(template_name).render(*args, **context)
return env.get_template(template_name).render(*args, **context)
def html(self, template_name, *args, **kwargs):
self.headers["Content-Type"] = "text/html; charset=utf-8"
self.body = self.render_template(template_name, *args, **kwargs)
def render_pdf(self, template_name, *args, **kwargs):
html = self.render_template(template_name, *args, **kwargs)
static_folder = Path(__file__).parent / "static"
stylesheets = [
static_folder / "app.css",
static_folder / "icomoon.css",
static_folder / "page.css",
]
if "css" in kwargs:
stylesheets.append(static_folder / kwargs["css"])
return HTML(string=html).write_pdf(stylesheets=stylesheets)
def pdf(self, template_name, *args, **kwargs):
self.body = self.render_pdf(template_name, *args, **kwargs)
mimetype = "application/pdf"
filename = kwargs.get("filename", "file.pdf")
self.headers["Content-Disposition"] = f'attachment; filename="{filename}"'
self.headers["Content-Type"] = f"{mimetype}; charset=utf-8"
def xlsx(self, body, filename=f"{config.SITE_NAME}.xlsx"):
self.body = body
@ -228,9 +254,7 @@ async def create_group(request, response):
members.append(request["user"].email)
group = Group.create(
id=slugify(form.get("name")),
name=form.get("name"),
members=members,
id=slugify(form.get("name")), name=form.get("name"), members=members
)
request["groups"].add_group(group)
request["groups"].persist()
@ -340,15 +364,31 @@ async def import_products(request, response, id):
@app.route("/livraison/{id}/producteurices")
@app.route("/livraison/{id}/producteurices.pdf")
async def list_producers(request, response, id):
delivery = Delivery.load(id)
response.html(
"list_products.html",
{
template_name = "list_products.html"
template_params = {
"edit_mode": True,
"list_only": True,
"delivery": delivery,
"referent": request.query.get("referent", None),
},
if request.url.endswith(b".pdf"):
response.pdf(template_name, template_params, filename=utils.prefix("producteurices.pdf", delivery),)
else:
response.html(template_name, template_params)
@app.route("/livraison/{id}/{producer}/bon-de-commande.pdf", methods=["GET"])
async def pdf_for_producer(request, response, id, producer):
delivery = Delivery.load(id)
date = delivery.to_date.strftime("%Y-%m-%d")
response.pdf(
"list_products.html",
{"list_only": True, "delivery": delivery, "producers": [producer]},
filename=utils.prefix(f"bon-de-commande-{producer}.pdf", delivery),
)
@ -432,10 +472,10 @@ async def create_product(request, response, delivery_id, producer_id):
@app.route("/livraison/{id}/gérer", methods=["GET"])
async def manage_delivery(request, response, id):
async def delivery_toolbox(request, response, id):
delivery = Delivery.load(id)
response.html(
"manage_delivery.html",
"delivery_toolbox.html",
{
"delivery": delivery,
"referents": [p.referent for p in delivery.producers.values()],
@ -446,56 +486,47 @@ async def manage_delivery(request, response, id):
@app.route("/livraison/{id}/envoi-email-referentes", methods=["GET", "POST"])
async def send_referent_emails(request, response, id):
delivery = Delivery.load(id)
date = delivery.to_date.strftime("%Y-%m-%d")
if request.method == "POST":
email_body = request.form.get("email_body")
email_subject = request.form.get("email_subject")
sent_mails = 0
for referent in delivery.get_referents():
producers = delivery.get_producers_for_referent(referent)
if any(
[delivery.producers[p].has_active_products(delivery) for p in producers]
):
summary = reports.summary(delivery, producers)
attachments = []
for producer in producers:
if delivery.producers[producer].has_active_products(delivery):
pdf_file = response.render_pdf(
"list_products.html",
{
"list_only": True,
"delivery": delivery,
"producers": [producer],
},
)
attachments.append(
(
utils.prefix(f"{producer}.pdf", delivery),
pdf_file,
"application/pdf",
)
)
if attachments:
sent_mails = sent_mails + 1
emails.send(
referent,
email_subject,
email_body,
copy=delivery.contact,
attachments=[
(f"{config.SITE_NAME}-{date}-{referent}.xlsx", summary)
],
attachments=attachments,
)
response.message("Le mail à bien été envoyé")
response.message(f"Un mail à été envoyé aux {sent_mails} référent⋅e⋅s")
response.redirect = f"/livraison/{id}/gérer"
response.html("prepare_referent_email.html", {"delivery": delivery})
@app.route("/livraison/{id}/bon-de-commande-referent⋅e", methods=["GET"])
async def download_referent_summary(request, response, id):
delivery = Delivery.load(id)
date = delivery.to_date.strftime("%Y-%m-%d")
if not request["user"].is_referent(delivery):
return
referent = request["user"].email
producers = delivery.get_producers_for_referent(referent)
summary = reports.summary(delivery, producers)
response.xlsx(summary, filename=f"{config.SITE_NAME}-{date}-{referent}.xlsx")
@app.route(
"/livraison/{id}/product⋅eur⋅rice/{producer}/bon-de-commande",
methods=["GET"],
)
async def download_producer_report(request, response, id, producer):
delivery = Delivery.load(id)
summary = reports.summary(delivery, [producer])
date = delivery.to_date.strftime("%Y-%m-%d")
response.xlsx(
summary, filename=f"{config.SITE_NAME}-{date}-{producer}-bon-de-commande.xlsx"
)
@app.route("/livraison/{id}/exporter", methods=["GET"])
async def export_products(request, response, id):
delivery = Delivery.load(id)
@ -636,7 +667,12 @@ async def send_order(request, response, id):
@app.route("/livraison/{id}/émargement", methods=["GET"])
async def signing_sheet(request, response, id):
delivery = Delivery.load(id)
response.html("signing_sheet.html", {"delivery": delivery})
response.pdf(
"signing_sheet.html",
{"delivery": delivery},
css="signing-sheet.css",
filename=utils.prefix("commandes-par-groupe.pdf", delivery),
)
@app.route("/livraison/{id}/importer/commande", methods=["POST"])
@ -730,6 +766,7 @@ async def adjust_product(request, response, id, ref):
@app.route("/livraison/{id}/solde", methods=["GET"])
@app.route("/livraison/{id}/solde.pdf", methods=["GET"])
@staff_only
async def delivery_balance(request, response, id):
delivery = Delivery.load(id)
@ -770,17 +807,25 @@ async def delivery_balance(request, response, id):
for debiter, amount, crediter in results:
results_dict[debiter][crediter] = amount
response.html(
"delivery_balance.html",
{
template_name = "delivery_balance.html"
template_args = {
"delivery": delivery,
"debiters": debiters,
"crediters": crediters,
"results": results_dict,
"debiters_groups": groups.groups,
"crediters_groups": producer_groups,
},
}
if request.url.endswith(b".pdf"):
date = delivery.to_date.strftime("%Y-%m-%d")
response.pdf(
template_name,
template_args,
filename=utils.prefix("répartition-des-chèques.pdf", delivery),
)
else:
response.html(template_name, template_args)
@app.route("/livraison/{id}/solde.xlsx", methods=["GET"])

View file

@ -11,13 +11,10 @@ def send(to, subject, body, html=None, copy=None, attachments=None):
text=body, html=html, subject=subject, mail_from=config.FROM_EMAIL
)
for filename, attachment in attachments:
message.attach(
filename=filename,
data=attachment,
mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8",
)
for filename, attachment, mime in attachments:
message.attach(filename=filename, data=attachment, mime=f"{mime} charset=utf-8")
config.SEND_EMAILS = False
if not config.SEND_EMAILS:
body = body.replace("https", "http")
return print("Sending email", str(body))

View file

@ -598,3 +598,56 @@ table.paiements td {
table.paiements tr:hover td {
background: #f2f2f2;
}
.container {
width: 600px;
margin: 100px auto;
}
.progressbar {
counter-reset: step;
}
.progressbar li {
list-style-type: none;
width: 20%;
float: left;
font-size: 12px;
position: relative;
text-align: center;
text-transform: uppercase;
color: #7d7d7d;
}
.progressbar li:before {
width: 30px;
height: 30px;
content: counter(step);
counter-increment: step;
line-height: 25px;
border: 2px solid #7d7d7d;
display: block;
text-align: center;
margin: 0 auto 10px auto;
border-radius: 50%;
background-color: white;
}
.progressbar li:after {
width: 100%;
height: 2px;
content: '';
position: absolute;
background-color: #7d7d7d;
top: 15px;
left: -50%;
z-index: -1;
}
.progressbar li:first-child:after {
content: none;
}
.progressbar li.active {
color: green;
}
.progressbar li.active:before {
border-color: #55b776;
}
.progressbar li.active + li:after {
background-color: #55b776;
}

28
copanier/static/page.css Normal file
View file

@ -0,0 +1,28 @@
@page {
size: "A4";
margin: 0cm;
size: landscape;
}
#download {
display: none;
}
@media print {
nav, .notification, .toolbox, .edit, .hide-on-print, .button{
display: none;
}
ul.delivery-head {
display: block !important;
}
ul.delivery-head li {
margin-bottom: 1.5em !important;
}
table.delivery {
page-break-after: always;
}
.page-break {
page-break-after: always;
}
}

View file

@ -1,5 +1,3 @@
table, tr, td {
border: 0px;
@page {
size: portrait !important;
}
tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}

View file

@ -18,12 +18,11 @@
{% endif %}
<section class="menu">
<h1><a href="/">{{ config.SITE_NAME }}</a> <small>{{ config.SITE_DESCRIPTION }}</small></h1>
{% block title %}<h2>{% if delivery %}{{ delivery.name }}{% endif %}{% block actions %}{% endblock %}{% endblock %}</h2>
<nav>
{% if request.user %}
{% if request.user.is_staff %}
<a class="button" href="/livraison"><i class="icon-hotairballoon"></i>&nbsp;Nouvelle livraison</a>&nbsp;
{% endif %}
<i class="icon-lock"></i>&nbsp;<span>{{ request["user"].email }} {% if request["user"].group_name %}({{ request["user"].group_name }}){% endif %}</span>
<i class="icon-lock"></i>&nbsp;<span>{{ request["user"].email }} {% if request["user"].group_name %}({{ request["user"].group_name }}){% endif %} <a href="/déconnexion">déconnexion</a></span>
{% endif %}
</nav>
</section>

View file

@ -1,13 +1,23 @@
{% extends "base.html" %}
{% block actions %}
{% include "includes/order_button.html" %}
{% endblock %}
{% block body %}
<h3>{{ delivery.name }} {% include "includes/order_button.html" %}</h3>
{% include "includes/delivery_head.html" %}
{% if request['user'].email == delivery.contact %}
<div class="notification info"><i class="icon-lightbulb"></i> Vous êtes la personne référente de cette distribution <a class="button" href="/livraison/{{ delivery.id }}/gérer">Voir la boîte à outils</a></div>
{% elif request['user'].email in delivery.get_referents() %}
<div class="notification info"><i class="icon-lightbulb"></i> Vous êtes référent⋅e pour cette distribution (merci !). <a class="button" href="/livraison/{{ delivery.id }}/producteurices?referent={{request['user'].email}}">Gérer les produits dont vous vous occupez</a></div>
{% endif %}
<ul class="progressbar">
<li {% if delivery.status == delivery.OPEN %}class="active"{% endif %}>Mise à jour des prix</li>
<li {% if delivery.status == delivery.OPEN %}class="active"{% endif %}>Ouverture des commandes</li>
<li {% if delivery.status == delivery.ADJUSTMENT %}class="active"{% endif %}>Ajustements</li>
<li {% if delivery.can_generate_reports %}class="active"{% endif %}>Achats par les référent⋅e⋅s</li>
<li>Distribution</li>
</ul>
<article class="delivery">
{% if delivery.has_products %}
{% include "includes/delivery_table.html" %}
@ -22,7 +32,7 @@
<ul class="toolbox">
{% if not delivery.is_archived and delivery.status == delivery.CLOSED %}
<li>
<a href="/livraison/{{ delivery.id }}/bon-de-commande.xlsx"><i class="icon-ribbon"></i> Bon de commande</a>
<a href="/livraison/{{ delivery.iddelivery }}/bon-de-commande.xlsx"><i class="icon-ribbon"></i> Bon de commande</a>
</li>
<li>
<a href="/livraison/{{ delivery.id }}/rapport-complet.xlsx"><i class="icon-grid"></i> Rapport complet</a>

View file

@ -1,6 +1,7 @@
{% extends "base.html" %}
{% block title %}<h1><i class="icon-wallet"></i>&nbsp; Répartition des paiements <a id="download" class="button" href="/livraison/{{ delivery.id }}/solde.pdf">Télécharger</a></h1>{% endblock %}
{% block body %}
<h1><i class="icon-wallet"></i> <a href="/livraison/{{ delivery.id }}">{{ delivery.name }}</a><br />Répartition des paiements</h1>
<p class="info">{{ delivery.name }} du {{ delivery.to_date | date }}.</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 groupe.</p>
<table class="paiements">
<tr>

View file

@ -16,13 +16,12 @@
<a class="button" href="/groupes"><i class="icon-globe"></i>&nbsp; Gérer les groupes / colocs</a>
<h3>Une fois les commandes passées (après le {{ delivery.order_before|date }})</h3>
<a class="button" href="/livraison/{{ delivery.id }}/bon-de-commande.xlsx"><i class="icon-download"></i>&nbsp; Télécharger le bon de commande global</a>
<a class="button" href="/livraison/{{ delivery.id }}/rapport-complet.xlsx"><i class="icon-download"></i>&nbsp; Télécharger le récap (global) des commandes</a>
<a class="button" href="/livraison/{{ delivery.id }}/producteurices.pdf"><i class="icon-download"></i>&nbsp; Télécharger les bons de livraison</a>
<a class="button" href="/livraison/{{ delivery.id }}/rapport-complet.xlsx"><i class="icon-download"></i>&nbsp; Télécharger le tableau des commandes</a>
<a class="button" href="/livraison/{{ delivery.id }}/envoi-email-referentes"><i class="icon-envelope"></i>&nbsp; Envoyer les infos de commande aux référent⋅e⋅s</a>
<h3>Pour préparer la distribution (le {{ delivery.from_date|date }})</h3>
<a class="button" href="/livraison/{{ delivery.id }}/émargement"><i class="icon-document"></i>&nbsp; Fiches de commandes par groupe</a>
<a class="button" href="/livraison/{{ delivery.id }}/rapport-complet.xlsx"><i class="icon-grid"></i>&nbsp; Télécharger le résumé général des commandes</a>
<a class="button" href="/livraison/{{ delivery.id }}/solde"><i class="icon-gears"></i>&nbsp; Faire la répartition des paiements</a>
{% endblock %}

View file

@ -1,6 +1,5 @@
{% extends "base.html" %}
{% block body %}
<h2>Livraisons à venir</h2>
{% with deliveries=incoming %}
{% include "includes/delivery_list.html" %}
{% endwith %}
@ -15,6 +14,11 @@
<hr>
{% endif %}
<ul class="toolbox">
{% if request.user.is_staff %}
<li>
<a class="button" href="/livraison"><i class="icon-hotairballoon"></i>&nbsp;Nouvelle livraison</a>&nbsp;
</li>
{% endif %}
<li>
<a href="/groupes" class="button"><i class="icon-globe"></i>&nbsp;Gérer les groupes / colocs</a>
</li>

View file

@ -4,11 +4,10 @@
{% if display_counts %}
<li><i class="icon-lightbulb"></i> <strong>{{ delivery.orders|length }}</strong> colocs</strong>, <strong>{{ delivery.products|length }}</strong> produits et <strong>{{ delivery.producers | length}}</strong> product⋅eurs⋅rices, <strong>{{ delivery.total }}€</strong></li>
{% else %}
<li><i class="icon-strategy"></i> <strong>Référent⋅e</strong> <a href="mailto:{{ delivery.contact }}">{{ delivery.contact }}</a></li>
<li class="hide-on-print"><i class="icon-strategy"></i> <strong>Référent⋅e</strong> <a href="mailto:{{ delivery.contact }}">{{ delivery.contact }}</a></li>
{% endif %}
<li><i class="icon-clock"></i> <strong>Date de livraison</strong> <time datetime="{{ delivery.from_date }}">{{ delivery.from_date|date|capitalize }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }}</time></li>
<li><i class="icon-hourglass"></i> {% if delivery.status == delivery.OPEN %}<strong>Date limite de commande</strong> <time datetime="{{ delivery.order_before.date() }}">{{ delivery.order_before|date|capitalize }}</time>{% elif delivery.status == delivery.ADJUSTMENT %}<strong>Ajustement en cours</strong>{% elif delivery.status == delivery.CLOSED %}<strong>Fermée</strong>{% else %}<strong>Archivée</strong>{% endif %}</li>
<li class="hide-on-print"><i class="icon-hourglass"></i> {% if delivery.status == delivery.OPEN %}<strong>Date limite de commande</strong> <time datetime="{{ delivery.order_before.date() }}">{{ delivery.order_before|date|capitalize }}</time>{% elif delivery.status == delivery.ADJUSTMENT %}<strong>Ajustement en cours</strong>{% elif delivery.status == delivery.CLOSED %}<strong>Fermée</strong>{% else %}<strong>Archivée</strong>{% endif %}</li>
{% if delivery.instructions %}<li><i class="icon-lightbulb"></i> <strong>À savoir</strong> {{ delivery.instructions }}</li>{% endif %}
{% if delivery.infos_url %}<li><i class="icon-global"></i><strong>Plus d'infos</strong> <a href="{{ delivery.infos_url }}" title="{{ delivery.infos_url }}">{{ delivery.infos_url|truncate(20)}}</a></li>{% endif %}
</ul>

View file

@ -1,19 +1,22 @@
{% if referent %}
{% if not producers and referent %}
{% set producers = delivery.get_producers_for_referent(referent) %}
{% else %}
{% elif not producers %}
{% set producers = delivery.producers %}
{% endif %}
{% for producer in producers %}
{% set producer_obj = delivery.producers[producer] %}
<h2>{{ producer }}
{% if edit_mode or request.user.is_staff or delivery.producers[producer].referent == request.user.email %}
{% if edit_mode or request.user.is_staff or producer_obj.referent == request.user.email %}
<span class="edit">
<a class="button" href="/livraison/{{ delivery.id }}/{{ producer }}/éditer"><i class="icon-ribbon"></i>&nbsp; Éditer</a>
<a class="button" href="/livraison/{{ delivery.id }}/{{ producer }}/ajouter-produit"><i class="icon-puzzle"></i>&nbsp; Ajouter un produit </a>
{% if delivery.can_generate_reports %}
<a class="button" href="/livraison/{{ delivery.id }}/{{ producer }}/bon-de-commande"><i class="icon-grid"></i>&nbsp; Télécharger le bon de commande</a>
<a class="button" href="/livraison/{{ delivery.id }}/{{ producer }}/bon-de-commande.pdf"><i class="icon-grid"></i>&nbsp; Télécharger le bon de commande</a>
{% endif %}
</span>
{% endif %}
</h2>
<h5>{% if delivery.producers[producer].description %}{{ delivery.producers[producer].description }}{% endif %}. Référent⋅e : {{ delivery.producers[producer].referent }} / {{ delivery.producers[producer].referent_tel }}</h5>
<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>
<table class="delivery">
<thead>
<tr>
@ -23,8 +26,8 @@
<th class="packing">Conditionnement</th>
{% endif %}
{% if edit_mode %}<th>Éditer</th>{% endif %}
{% if not list_only %}
<th class="amount">Total</th>
{% if not list_only %}
{% for orderer, order in delivery.orders.items() %}
{% set orderer_name = request.groups.groups[orderer].name %}
<th class="person{% if delivery.is_passed and not order.paid %} not-paid{% endif %}">
@ -47,20 +50,19 @@
<td class="packing">{% if product.packing %}{{ product.packing }} x {% endif %} {{ product.unit }}</td>
{% endif %}
{% if edit_mode %}<td><a href="/livraison/{{ delivery.id }}/{{ product.producer }}/{{ product.ref }}/éditer">modifier</a></td>{% endif %}
{% if not list_only %}
<th{% if delivery.status == delivery.ADJUSTMENT and delivery.product_missing(product) %} class="missing" title="Les commandes individuelles ne correspondent pas aux conditionnements"{% endif %}>
{{ delivery.product_wanted(product) }}
{% if delivery.status == delivery.ADJUSTMENT and delivery.product_missing(product) %} ({{ delivery.product_missing(product) }})
{% if request.user.is_staff %}<a href="/livraison/{{ delivery.id }}/ajuster/{{ product.ref }}" class="button" title="ajuster le produit">ajuster</a>{% endif %}
{% endif %}
</th>
{% if not list_only %}
{% for email, order in delivery.orders.items() %}
<td title="Commandé: {{ order[product.ref].wanted }} — Ajusté: {{ "%+d"|format(order[product.ref].adjustment) }}">{{ order[product.ref].quantity or "—" }}</td>
{% endfor %}
{% endif %}
</tr>
{% endfor %}
{% if not list_only %}
<tr>
<th class="total"><i class="icon-pricetags"></i> Total</th><td></td>
{% if delivery.has_packing %}
@ -70,11 +72,12 @@
<td></td>
{% endif %}
<th class="total">{{ delivery.total_for_producer(producer) }} €</th>
{% if not list_only %}
{% for email, order in delivery.orders.items() %}
<td>{{ order.total(delivery.get_products_by(producer)) }} €</td>
{% endfor %}
</tr>
{% endif %}
</tr>
</tbody>
</table>
{% endfor %}

View file

@ -1,8 +1,9 @@
{% extends "base.html" %}
{% block body %}
<h3>{{ delivery.name }}</h3>
{% if referent %}<p>Voici la liste des product⋅eurs⋅rices dont {{ referent }} est référent⋅e. <a class="button" href="/livraison/{{delivery.id}}/producteurices">voir tous les produits</a></p>{% endif %}
<p class="hide-on-print">
<a href="/livraison/{{ delivery.id }}/producteurices.pdf{% if referent %}?referent={{ referent }}{% endif %}">Télécharger la liste des commandes en PDF</a>
{% if referent %}Voici la liste des product⋅eurs⋅rices dont {{ referent }} est référent⋅e. <a class="button" href="/livraison/{{delivery.id}}/producteurices">voir tous les produits</a>{% endif %}
</p>
<article class="delivery">
{% include "includes/delivery_table.html" %}
</article>

View file

@ -12,7 +12,7 @@ Bonjour,
Et voilà, les commandes maintenant terminées, il est maintenant temps de passer à l'action !
En pièce-jointe, les informations pour les producteurs⋅rices dont tu est référent⋅e.
Tu peux aussi retrouver le doc à cette URL : https://{{ request.host }}/livraison/{{ delivery.id }}/bon-de-commande-referent⋅e
Tu peux aussi retrouver le doc à cette URL : https://{{ request.host }}/livraison/{{ delivery.id }}/producteurices
Rendez-vous pour la distribution, le {{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }} à {{ delivery.where }}.

View file

@ -1,16 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>{% if title %}{{ title }} - {% endif %}{{ config.SITE_NAME }}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="/static/signing-sheet.css">
</head>
<body>
<h2>{{ delivery.name }} {{ delivery.from_date.date() }} - liste d'émargement</h2>
{% extends "base.html" %}
{% block body %}
{% for email, order in delivery.orders.items() %}
<h3>{{ request.groups.groups[email].name }}</h3>
{% include "includes/order_summary.html" %}
<hr>
<hr class="page-break">
{% endfor %}
</body>
{% endblock %}

View file

@ -22,3 +22,8 @@ def read_token(token):
return jwt.decode(token, config.SECRET, algorithms=[config.JWT_ALGORITHM])
except (jwt.DecodeError, jwt.ExpiredSignatureError):
return {}
def prefix(string, delivery):
date = delivery.to_date.strftime("%Y-%m-%d")
return f"{config.SITE_NAME}-{date}-{string}"