mirror of
https://framagit.org/la-chariotte/la-chariotte.git
synced 2025-05-02 11:52:27 +02:00
grouped order sheet generation - part 1
This commit is contained in:
parent
af466f960f
commit
6432e99c58
6 changed files with 222 additions and 4 deletions
|
@ -130,6 +130,8 @@ wheel==0.40.0
|
||||||
# via pip-tools
|
# via pip-tools
|
||||||
zipp==3.15.0
|
zipp==3.15.0
|
||||||
# via importlib-metadata
|
# via importlib-metadata
|
||||||
|
xhtml2pdf==0.2.11
|
||||||
|
# à la main : il faudrait l'ajouter dans le pyproject
|
||||||
|
|
||||||
# The following packages are considered to be unsafe in a requirements file:
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
# pip
|
# pip
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
{% block title %}{{ grouped_order }} - Gestion{% endblock %}
|
{% block title %}{{ grouped_order }} - Gestion{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<p class="desktop-hidden mobile-content-title">
|
<p class="desktop-hidden mobile-content-title">
|
||||||
{% block content_title %}{{ grouped_order }} : gestion de la commande{% endblock %}
|
{% block content_title %}{{ grouped_order }} : gestion de la commande{% endblock %}
|
||||||
</p>
|
</p>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="button is-light" href={% url 'order:grouped_order_detail' grouped_order.id %}>Retour à la page de commande</a>
|
<a class="button is-light" href={% url 'order:grouped_order_detail' grouped_order.id %}>Retour à la page de commande</a>
|
||||||
<a class="button is-primary" href="{% url 'order:index' %}">Mes commandes</a>
|
<a class="button is-primary" href="{% url 'order:index' %}">Mes commandes</a>
|
||||||
|
|
174
la_chariotte/order/templates/order/grouped_order_sheet.html
Normal file
174
la_chariotte/order/templates/order/grouped_order_sheet.html
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>
|
||||||
|
Commande groupée - date
|
||||||
|
</title>
|
||||||
|
<style type="text/css">
|
||||||
|
@page {
|
||||||
|
{% if headers|length > 6 %}
|
||||||
|
size: letter landscape;
|
||||||
|
{% else %}
|
||||||
|
size: A4;
|
||||||
|
{% endif %}
|
||||||
|
margin: 2cm 1.5cm;
|
||||||
|
@frame footer {
|
||||||
|
-pdf-frame-content: footer;
|
||||||
|
bottom: 0cm;
|
||||||
|
height: 1.5cm;
|
||||||
|
right: 0cm;
|
||||||
|
width: 3.5cm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 11pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.green {
|
||||||
|
color: #008000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: #ff0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large {
|
||||||
|
font-size: 120%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: 1px black solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
vertical-align: center;
|
||||||
|
padding: 3px 2px 2px 2px;
|
||||||
|
line-height: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
text-align: center;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 style="text-align: center">
|
||||||
|
{{ name }} - {{ delivery_date }}
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
Produits : {% for item in items.all %}
|
||||||
|
{{ item }}
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% if items %}
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="text-align: center">Nom</th>
|
||||||
|
{% for item in items %}
|
||||||
|
<th style="word-break: break-all">
|
||||||
|
{{ item.name }}
|
||||||
|
</th>
|
||||||
|
{% endfor %}
|
||||||
|
<th style="width: 2cm">Prix</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th style="background-color: #bababa">Total</th>
|
||||||
|
{% for item in items %}
|
||||||
|
<th style="text-align: center">{{ item.ordered_nb }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% for order in orders_dict %}
|
||||||
|
<tr>
|
||||||
|
poeut
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
<tr>
|
||||||
|
<th style="text-align: left">TOTAL</th>
|
||||||
|
{% for total in totals %}
|
||||||
|
<th style="text-align: center">
|
||||||
|
{{ total }}
|
||||||
|
{% endfor %} {% if include_prices %}
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th style="text-align: right">{{ total_to_pay|floatformat:2 }} €</th>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for user in user_info %}
|
||||||
|
<tr> {% if include_prices %}
|
||||||
|
<td style="text-align: right">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 8cm; text-align: left">Nom</th>
|
||||||
|
<th style="width: 4cm">{{Quantité}}</th>
|
||||||
|
<th style="width: 4cm">Récupéré ?</th>
|
||||||
|
|
||||||
|
{% if include_prices %}
|
||||||
|
<th style="width: 3cm">À payer</th>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for user in user_info %}
|
||||||
|
<tr>
|
||||||
|
<td style="width: 6cm"></td>
|
||||||
|
{% if include_prices %}
|
||||||
|
<td style="text-align: right">
|
||||||
|
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>TOTAL</th>
|
||||||
|
{% for total in totals %}
|
||||||
|
<th style="text-align: center">{{ total }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
<th style="background-color: #ccc; width: 4cm"></th>
|
||||||
|
|
||||||
|
{% if include_prices %}
|
||||||
|
<th style="text-align: right">{{ total_to_pay|floatformat:2 }} €</th>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
Page
|
||||||
|
<pdf:pagenumber />
|
||||||
|
/
|
||||||
|
<pdf:pagecount />
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -30,4 +30,9 @@ urlpatterns = [
|
||||||
views.ItemCreateView.as_view(),
|
views.ItemCreateView.as_view(),
|
||||||
name="item_create",
|
name="item_create",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"<int:pk>/gerer/imprimer",
|
||||||
|
views.GroupedOrderSheetView.as_view(),
|
||||||
|
name="grouped_order_sheet",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import FileResponse, HttpResponse, HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
|
from django.template.loader import get_template
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
from xhtml2pdf import pisa
|
||||||
|
|
||||||
from .forms import GroupedOrderForm, ItemCreateForm
|
from .forms import GroupedOrderForm, ItemCreateForm
|
||||||
from .models import GroupedOrder, Item, Order, OrderAuthor, OrderedItem
|
from .models import GroupedOrder, Item, Order, OrderAuthor, OrderedItem
|
||||||
|
@ -184,3 +188,35 @@ class OrderDetailView(generic.DetailView):
|
||||||
"""Confirmation page after a user orders"""
|
"""Confirmation page after a user orders"""
|
||||||
|
|
||||||
model = Order
|
model = Order
|
||||||
|
|
||||||
|
class GroupedOrderSheetMixin():
|
||||||
|
def get_grouped_order_infos(self,grouped_order_id):
|
||||||
|
grouped_order = get_object_or_404(GroupedOrder,id=grouped_order_id)
|
||||||
|
|
||||||
|
# Get ordered items
|
||||||
|
items = grouped_order.item_set.filter(ordered_nb__gt=0)
|
||||||
|
|
||||||
|
# Get content of orders
|
||||||
|
orders_values = []
|
||||||
|
for order in grouped_order.order_set.all():
|
||||||
|
for ordered_item in order.ordered_items.all():
|
||||||
|
orders_values[order.id][ordered_item.id] = ordered_item.nb
|
||||||
|
|
||||||
|
return {"name": grouped_order.name,"delivery_date":grouped_order.delivery_date,"items":items,"orders":orders_dict}
|
||||||
|
|
||||||
|
class GroupedOrderSheetView(GroupedOrderOverview, GroupedOrderSheetMixin):
|
||||||
|
template_name = "order/grouped_order_sheet.html"
|
||||||
|
|
||||||
|
def get(self, request, pk):
|
||||||
|
# ferme = Ferme.get_or_404(ferme_id)
|
||||||
|
# ferme.check_access(request.user)
|
||||||
|
|
||||||
|
grouped_order_sheet_info = self.get_grouped_order_infos(pk)
|
||||||
|
# should_include_prices = True if request.GET.get("with_prices", False) else False
|
||||||
|
# delivery_sheet_info["include_prices"] = should_include_prices
|
||||||
|
template = get_template(self.template_name)
|
||||||
|
html = template.render(grouped_order_sheet_info)
|
||||||
|
|
||||||
|
result = BytesIO()
|
||||||
|
pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), result)
|
||||||
|
return HttpResponse(result.getvalue(), content_type="application/pdf")
|
|
@ -26,6 +26,7 @@ dev = [
|
||||||
"pytest-cov>=4,<5",
|
"pytest-cov>=4,<5",
|
||||||
"diff-cover>=4,<5",
|
"diff-cover>=4,<5",
|
||||||
"pytest-black<1",
|
"pytest-black<1",
|
||||||
|
# il faudrait ajouter xhtml2pdf, mais la génération des requirements ne marche pas
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
|
|
Loading…
Reference in a new issue