pdf sheet generation - part 2

This commit is contained in:
Laetitia Getti 2023-05-25 16:32:49 +02:00
parent 761a28770c
commit 26f7c313fc
4 changed files with 161 additions and 118 deletions

View file

@ -36,14 +36,15 @@
<button class="button is-info" onclick="copyLink()">Copier le lien</button>
</div>
<div class="column">
<p>Pour vous aider à distribuer les produits le jour J, vous pouvez imprimer la liste des commandes :
<a href="{% url 'order:grouped_order_sheet' grouped_order.id %}">ici</a></p>
<p>Pour vous aider à distribuer les produits le jour J, vous pouvez imprimer la liste des commandes :</p>
<a class="button is-info" href="{% url 'order:grouped_order_sheet' grouped_order.id %}" target="_blank">Liste des commandes</a>
</div>
</div>
</div>
<div class="box">
<p class="title">Produits commandés</p>
{% if grouped_order.item_set.all %}
<table class="table">
<thead>
<tr>
@ -70,10 +71,14 @@
<th>{{ grouped_order.total_price }} €</th>
</tfoot>
</table>
{% else %}
<p>Vous n'avez pas ajouté de produits à cette commande groupée. Ajoutez-en <a href="{% url 'order:manage_items' %}">ici</a></p>
{% endif %}
</div>
<div class="box">
<p class="title">Liste des commandes</p>
{% if grouped_order.order_set.all %}
<table class="table">
<thead>
<tr>
@ -97,6 +102,9 @@
<th></th>
</tfoot>
</table>
{% else %}
<p>Personne n'a encore commandé. Partagez l'info à votre entourage !</p>
{% endif %}
</div>
{% endblock %}

View file

@ -3,11 +3,11 @@
<head>
<meta charset="UTF-8" />
<title>
Commande groupée - date
{{ name }} - Liste des commandes
</title>
<style type="text/css">
@page {
{% if headers|length > 6 %}
{% if items|length > 6 %}
size: letter landscape;
{% else %}
size: A4;
@ -18,7 +18,7 @@
bottom: 0cm;
height: 1.5cm;
right: 0cm;
width: 3.5cm;
width: 10cm;
}
}
@ -27,26 +27,10 @@
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;
@ -70,13 +54,7 @@
<h1 style="text-align: center">
{{ name }} - {{ delivery_date }}
</h1>
<p>
Produits : {% for item in items.all %}
{{ item }}
{% endfor %}
</p>
{% if items %}
<table>
<thead>
<tr>
@ -90,82 +68,46 @@
</tr>
</thead>
<tbody>
<tr>
<th style="background-color: #bababa">Total</th>
<tr style="background-color: #bababa">
<th style="text-align: left">Prix unitaire</th>
{% for item in items %}
<th style="text-align: center">{{ item.ordered_nb }}</th>
<th>
{{ item.price }} €
</th>
{% endfor %}
</tr>
{% for order in orders_dict %}
<tr>
poeut
</tr>
{% endfor %}
<tr>
<tr style="background-color: #bababa">
<th style="text-align: left">TOTAL</th>
{% for total in totals %}
<th style="text-align: center">
{{ total }}
{% endfor %} {% if include_prices %}
{% for item in items %}
<th>
{{ item.ordered_nb }}
</th>
<th style="text-align: right">{{ total_to_pay|floatformat:2 }} €</th>
{% endif %}
{% endfor %}
<th>{{ total_price }} €</th>
</tr>
{% for user in user_info %}
<tr> {% if include_prices %}
<td style="text-align: right">
</td>
{% endif %}
</tr>
{% endfor %}
{% for order, ordered_items in orders_dict.items %}
<tr>
<th>
{{ order.author }}
</th>
{% for ordered_item in ordered_items %}
<th>
{{ ordered_item }}
</th>
{% endfor %}
<th>
{{ order.price }} €
</th>
</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>
Aucun produit n'a été commandé
{% endif %}
<div id="footer">
Page
Liste générée par la Chariotte - chariotte.fr | Page
<pdf:pagenumber />
/
<pdf:pagecount />

View file

@ -5,7 +5,7 @@ from django.contrib import auth
from django.urls import reverse
from django.utils import timezone
from la_chariotte.order.models import GroupedOrder, Item, Order, OrderAuthor
from la_chariotte.order import models
pytestmark = pytest.mark.django_db
@ -18,11 +18,29 @@ def create_grouped_order(
"""
date = timezone.now().date() + datetime.timedelta(days=days_before_delivery_date)
deadline = timezone.now() + datetime.timedelta(days=days_before_deadline)
return GroupedOrder.objects.create(
return models.GroupedOrder.objects.create(
name=name, orga=orga_user, delivery_date=date, deadline=deadline
)
def order_items_in_grouped_order(grouped_order):
"""Creates 2 OrderedItems and orders for those items in the given grouped order"""
item_1 = grouped_order.item_set.create(name="test item", price="2")
item_2 = grouped_order.item_set.create(name="test item 2", price="9")
author = models.OrderAuthor.objects.create(
first_name="bob", last_name="lescargot", phone="000", email="bob@escargot.fr"
)
order = grouped_order.order_set.create(author=author)
models.OrderedItem.objects.create(order=order, item=item_1, nb=3)
models.OrderedItem.objects.create(order=order, item=item_2, nb=2)
item_1.compute_ordered_nb()
item_2.compute_ordered_nb()
order.compute_order_price()
grouped_order.compute_total_price()
grouped_order.save()
return order
class TestGroupedOrderIndexView:
def test_anonymous_user_redirection(self, client):
"""
@ -205,7 +223,7 @@ class TestGroupedOrderIndexView:
class TestGroupedOrderDetailView:
def test_order_item(self, client, other_user):
"""
From the OrderDetailView, we order an item using the order form, and it creates an Order with an Ordered_item inside
From the OrderDetailView, we order an item using the order form, and it creates an models.Order with an Ordered_item inside
"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
@ -213,10 +231,10 @@ class TestGroupedOrderDetailView:
name="gr order test",
orga_user=other_user,
)
item = Item.objects.create(
item = models.Item.objects.create(
name="test item 1", grouped_order=grouped_order, price=1
)
item2 = Item.objects.create(
item2 = models.Item.objects.create(
name="test item 2", grouped_order=grouped_order, price=5
)
detail_url = reverse(
@ -249,7 +267,7 @@ class TestGroupedOrderDetailView:
},
)
assert response.status_code == 302
order = Order.objects.get(grouped_order=grouped_order.pk)
order = models.Order.objects.get(grouped_order=grouped_order.pk)
assert response.url == reverse(
"order:order_confirm",
kwargs={
@ -259,12 +277,12 @@ class TestGroupedOrderDetailView:
)
item.refresh_from_db()
item2.refresh_from_db()
assert OrderAuthor.objects.first().first_name == "Prénom"
assert OrderAuthor.objects.first().email == "test@mail.fr"
assert OrderAuthor.objects.first().phone == "0645632569"
assert models.OrderAuthor.objects.first().first_name == "Prénom"
assert models.OrderAuthor.objects.first().email == "test@mail.fr"
assert models.OrderAuthor.objects.first().phone == "0645632569"
assert item.ordered_nb == 4
assert item2.ordered_nb == 1
order = Order.objects.first()
order = models.Order.objects.first()
assert order.ordered_items.count() == 2
assert order.articles_nb == 5
assert order.price == 9
@ -280,7 +298,7 @@ class TestGroupedOrderDetailView:
name="gr order test",
orga_user=other_user,
)
item = Item.objects.create(
item = models.Item.objects.create(
name="test item 1", grouped_order=grouped_order, price=1
)
detail_url = reverse(
@ -310,7 +328,7 @@ class TestGroupedOrderDetailView:
"email": "test@mail.fr",
},
)
order = Order.objects.first()
order = models.Order.objects.first()
order.articles_nb == 0
assert response.status_code == 200
assert (
@ -322,7 +340,7 @@ class TestGroupedOrderDetailView:
class TestGroupedOrderOverview:
def test_get_overview(self, client_log):
"""
From the OrderDetailView, we order an item using the order form, and it creates an Order with an Ordered_item inside
From the OrderDetailView, we order an item using the order form, and it creates an models.Order with an Ordered_item inside
"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
@ -330,7 +348,7 @@ class TestGroupedOrderOverview:
name="gr order test",
orga_user=auth.get_user(client_log),
)
item = Item.objects.create(
item = models.Item.objects.create(
name="test item 1", grouped_order=grouped_order, price=2
)
@ -421,7 +439,7 @@ class TestGroupedOrderCreateView:
A logged user gets the grouped order creation page, and creates a grouped order.
They are redirected to the manage items page.
"""
assert GroupedOrder.objects.count() == 0
assert models.GroupedOrder.objects.count() == 0
create_gorder_url = reverse("order:create_grouped_order")
response = client_log.get(create_gorder_url)
assert response.status_code == 200
@ -433,7 +451,7 @@ class TestGroupedOrderCreateView:
)
assert response.status_code == 302
assert response.url.endswith("gerer-produits")
assert GroupedOrder.objects.count() == 1
assert models.GroupedOrder.objects.count() == 1
def test_create_grouped_order__anonymous_user(self, client):
create_gorder_url = reverse("order:create_grouped_order")
@ -523,7 +541,7 @@ class TestItemCreateView:
"pk": grouped_order.pk,
},
)
assert Item.objects.first().name == "titre item"
assert models.Item.objects.first().name == "titre item"
response = client_log.get(response.url)
assert "titre item" in response.content.decode()
@ -567,3 +585,70 @@ class TestItemCreateView:
)
response = client_log.post(create_item_view_url, {"name": "titre item"})
assert response.status_code == 403
class TestGroupedOrderSheetView:
def test_get__not_orga(self, client_log, other_user):
"""A user that is not organiszer of the GO accesses the sheet view.
They get a 403 error"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=other_user,
)
generate_sheet_url = reverse(
"order:grouped_order_sheet",
kwargs={
"pk": grouped_order.pk,
},
)
response = client_log.get(generate_sheet_url)
assert response.status_code == 403
def test_get__not_orga(self, client, other_user):
"""An anonymous user accesses the sheet view.
They get redirected to login page"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=other_user,
)
generate_sheet_url = reverse(
"order:grouped_order_sheet",
kwargs={
"pk": grouped_order.pk,
},
)
response = client.get(generate_sheet_url)
assert response.status_code == 302
assert response.url == f"{reverse('accounts:login')}?next={generate_sheet_url}"
def test_get_pdf_sheet(self, client_log, other_user):
"""The orga of the grouped models.Order accesses the pdf sheet"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=auth.get_user(client_log),
)
generate_sheet_url = reverse(
"order:grouped_order_sheet",
kwargs={
"pk": grouped_order.pk,
},
)
response = client_log.get(generate_sheet_url)
assert response.status_code == 200
assert response.context["name"] == "gr order test"
assert response.context["delivery_date"] == grouped_order.delivery_date
assert response.context["items"].count() == 0
order = order_items_in_grouped_order(grouped_order)
response = client_log.get(generate_sheet_url)
assert response.status_code == 200
assert response.context["name"] == "gr order test"
assert response.context["delivery_date"] == grouped_order.delivery_date
assert response.context["items"].count() == 2
assert response.context["orders_dict"][order] == [3, 2]
assert response.context["total_price"] == 24

View file

@ -191,36 +191,44 @@ class OrderDetailView(generic.DetailView):
class GroupedOrderSheetMixin:
"""Mixin for grouped order info export (pdf sheet and csv)"""
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)
items = grouped_order.item_set.filter(ordered_nb__gt=0).order_by("name")
# Get content of orders
orders_values = []
# Get content of orders as a dict {order : [ordered_nb for item 1, ordered_nb for item 2, ...]}
orders_dict = {}
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
ordered_values = [] # ordered_values list as value of the dict
for item in items: # items that has actually been ordered
# find the ordered nb of this item in this order
# if no item of the type has been ordered in this order, put 0
value = order.ordered_items.filter(item=item).first()
value = value.nb if value else 0
ordered_values.append(value)
orders_dict[order] = ordered_values # order as key of the dict
return {
"name": grouped_order.name,
"delivery_date": grouped_order.delivery_date,
"items": items,
"orders": orders_dict,
"orders_dict": orders_dict,
"total_price": grouped_order.total_price,
}
class GroupedOrderSheetView(GroupedOrderOverview, GroupedOrderSheetMixin):
"""View to get a pdf sheet summing up the grouped order for delivery"""
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
# delivery_sheet_info["include_prices"] = should_include_prices - à ajouter plus tard
template = get_template(self.template_name)
html = template.render(grouped_order_sheet_info)