mirror of
https://framagit.org/la-chariotte/la-chariotte.git
synced 2025-05-02 20:01:51 +02:00
csv export of a grouped order
This commit is contained in:
parent
52b7804281
commit
25d0ef5604
5 changed files with 152 additions and 15 deletions
|
@ -59,14 +59,14 @@
|
||||||
<li>
|
<li>
|
||||||
<a id="partager-opener" class="tablinks" onclick="openTab('partager')">
|
<a id="partager-opener" class="tablinks" onclick="openTab('partager')">
|
||||||
<span class="is-hidden-desktop">Partager</span>
|
<span class="is-hidden-desktop">Partager</span>
|
||||||
<span class="is-hidden-touch">Partager et imprimer</span>
|
<span class="is-hidden-touch">Partager et exporter</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="partager" class="box tabcontent">
|
<div id="partager" class="box tabcontent">
|
||||||
<p class="title">Partager et imprimer</p>
|
<p class="title">Partager et exporter</p>
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
{% if not grouped_order.is_to_be_delivered %}
|
{% if not grouped_order.is_to_be_delivered %}
|
||||||
|
@ -87,9 +87,13 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<p>Pour vous aider à distribuer les produits le jour J, vous pouvez imprimer la liste des commandes :</p>
|
<p>Pour vous aider à distribuer les produits le jour J, vous pouvez télécharger la liste des commandes
|
||||||
|
au format PDF pour l'<strong>imprimer</strong>, ou au format CSV pour l'<strong>afficher dans un tableur</strong> :</p>
|
||||||
<a class="button is-info" href="{% url 'order:grouped_order_sheet' grouped_order.id %}" target="_blank">
|
<a class="button is-info" href="{% url 'order:grouped_order_sheet' grouped_order.id %}" target="_blank">
|
||||||
<i class="fa fa-file mr-3" aria-hidden="true"></i>Liste des commandes
|
<i class="fa fa-file-pdf-o mr-3" aria-hidden="true"></i>Commandes en PDF
|
||||||
|
</a>
|
||||||
|
<a class="button is-info" href="{% url 'order:grouped_order_csv_export' grouped_order.id %}" target="_blank">
|
||||||
|
<i class="fa fa-file-excel-o mr-3" aria-hidden="true"></i>Commandes en CSV
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1288,7 +1288,7 @@ class TestGroupedOrderSheetView:
|
||||||
class TestExportGroupedOrderEmailAddressesToCSVView:
|
class TestExportGroupedOrderEmailAddressesToCSVView:
|
||||||
def test_user_not_logged_redirect(self, client, other_user):
|
def test_user_not_logged_redirect(self, client, other_user):
|
||||||
"""
|
"""
|
||||||
A user that is not logged access the email list. They get redirected to the login view
|
A user that is not logged accesses the email list. They get redirected to the login view
|
||||||
"""
|
"""
|
||||||
grouped_order = create_grouped_order(
|
grouped_order = create_grouped_order(
|
||||||
days_before_delivery_date=5,
|
days_before_delivery_date=5,
|
||||||
|
@ -1310,7 +1310,7 @@ class TestExportGroupedOrderEmailAddressesToCSVView:
|
||||||
|
|
||||||
def test_user_not_orga_forbidden(self, client_log, other_user):
|
def test_user_not_orga_forbidden(self, client_log, other_user):
|
||||||
"""
|
"""
|
||||||
A user that is not orga cannot access the email list.
|
A user that is not orga cannot accesses the email list.
|
||||||
They get a 403 forbidden error
|
They get a 403 forbidden error
|
||||||
"""
|
"""
|
||||||
grouped_order = create_grouped_order(
|
grouped_order = create_grouped_order(
|
||||||
|
@ -1328,9 +1328,9 @@ class TestExportGroupedOrderEmailAddressesToCSVView:
|
||||||
response = client_log.get(email_list_view_url)
|
response = client_log.get(email_list_view_url)
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
|
|
||||||
def test_email_addresses(self, client_log, other_user):
|
def test_email_addresses(self, client_log):
|
||||||
"""
|
"""
|
||||||
The grouped order orga accesses the email addresses list
|
The grouped order orga accesseses the email addresses list
|
||||||
"""
|
"""
|
||||||
grouped_order = create_grouped_order(
|
grouped_order = create_grouped_order(
|
||||||
days_before_delivery_date=5,
|
days_before_delivery_date=5,
|
||||||
|
@ -1352,3 +1352,81 @@ class TestExportGroupedOrderEmailAddressesToCSVView:
|
||||||
response = client_log.get(email_list_view_url)
|
response = client_log.get(email_list_view_url)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert email in response.content.decode()
|
assert email in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
class TestExportGroupedOrderToCSVView:
|
||||||
|
def test_user_not_logged_redirect(self, client, other_user):
|
||||||
|
"""
|
||||||
|
A user that is not logged accesses the csv view. They get redirected to the login view
|
||||||
|
"""
|
||||||
|
grouped_order = create_grouped_order(
|
||||||
|
days_before_delivery_date=5,
|
||||||
|
days_before_deadline=2,
|
||||||
|
name="gr order test",
|
||||||
|
orga_user=other_user,
|
||||||
|
)
|
||||||
|
csv_view_url = reverse(
|
||||||
|
"order:grouped_order_csv_export",
|
||||||
|
kwargs={
|
||||||
|
"pk": grouped_order.pk,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert auth.get_user(client).is_anonymous
|
||||||
|
response = client.get(csv_view_url)
|
||||||
|
assert response.status_code == 302
|
||||||
|
assert response.url.startswith(reverse("accounts:login"))
|
||||||
|
assert response.url.endswith(csv_view_url)
|
||||||
|
|
||||||
|
def test_user_not_orga_forbidden(self, client_log, other_user):
|
||||||
|
"""
|
||||||
|
A user that is not orga cannot accesses the csv view.
|
||||||
|
They get a 403 forbidden error
|
||||||
|
"""
|
||||||
|
grouped_order = create_grouped_order(
|
||||||
|
days_before_delivery_date=5,
|
||||||
|
days_before_deadline=2,
|
||||||
|
name="gr order test",
|
||||||
|
orga_user=other_user,
|
||||||
|
)
|
||||||
|
csv_view_url = reverse(
|
||||||
|
"order:grouped_order_csv_export",
|
||||||
|
kwargs={
|
||||||
|
"pk": grouped_order.pk,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = client_log.get(csv_view_url)
|
||||||
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
def test_csv_export(self, client_log):
|
||||||
|
"""
|
||||||
|
The grouped order orga accesses the csv view
|
||||||
|
"""
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
|
||||||
|
order = order_items_in_grouped_order(grouped_order)
|
||||||
|
csv_view_url = reverse(
|
||||||
|
"order:grouped_order_csv_export",
|
||||||
|
kwargs={
|
||||||
|
"pk": grouped_order.pk,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = client_log.get(csv_view_url)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert order.author.first_name in response.content.decode()
|
||||||
|
assert str(order.ordered_items.first().nb) in response.content.decode()
|
||||||
|
assert order.ordered_items.first().item.name in response.content.decode()
|
||||||
|
assert (
|
||||||
|
str(order.ordered_items.first().item.price).replace(".", ",")
|
||||||
|
in response.content.decode()
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
str(order.ordered_items.first().item.ordered_nb)
|
||||||
|
in response.content.decode()
|
||||||
|
)
|
||||||
|
assert order.author.email in response.content.decode()
|
||||||
|
assert order.author.phone in response.content.decode()
|
||||||
|
|
|
@ -65,4 +65,9 @@ urlpatterns = [
|
||||||
views.ExportGroupedOrderEmailAddressesToCSVView.as_view(),
|
views.ExportGroupedOrderEmailAddressesToCSVView.as_view(),
|
||||||
name="email_list",
|
name="email_list",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"<int:pk>/gerer/csv",
|
||||||
|
views.ExportGroupedOrderToCSVView.as_view(),
|
||||||
|
name="grouped_order_csv_export",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
# fmt: off
|
# fmt: off
|
||||||
from .grouped_order import (DownloadGroupedOrderSheetView,
|
from .grouped_order import (DownloadGroupedOrderSheetView,
|
||||||
ExportGroupedOrderEmailAddressesToCSVView,
|
ExportGroupedOrderEmailAddressesToCSVView,
|
||||||
|
ExportGroupedOrderToCSVView,
|
||||||
GroupedOrderAddItemsView, GroupedOrderCreateView,
|
GroupedOrderAddItemsView, GroupedOrderCreateView,
|
||||||
GroupedOrderDeleteView, GroupedOrderDetailView,
|
GroupedOrderDeleteView, GroupedOrderDetailView,
|
||||||
GroupedOrderDuplicateView, GroupedOrderOverview,
|
GroupedOrderDuplicateView, GroupedOrderExportView,
|
||||||
GroupedOrderSheetView, GroupedOrderUpdateView,
|
GroupedOrderOverview, GroupedOrderUpdateView,
|
||||||
IndexView)
|
IndexView)
|
||||||
from .item import ItemCreateView, ItemDeleteView
|
from .item import ItemCreateView, ItemDeleteView
|
||||||
from .order import OrderDeleteView, OrderDetailView, place_order
|
from .order import OrderDeleteView, OrderDetailView, place_order
|
||||||
|
|
|
@ -229,7 +229,7 @@ class GroupedOrderAddItemsView(UserPassesTestMixin, generic.ListView):
|
||||||
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
|
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
|
||||||
|
|
||||||
|
|
||||||
class GroupedOrderSheetView(UserPassesTestMixin, generic.DetailView):
|
class GroupedOrderExportView(UserPassesTestMixin, generic.DetailView):
|
||||||
"""View for gathering information about the groupedorder, in order to download it
|
"""View for gathering information about the groupedorder, in order to download it
|
||||||
in the DownloadGroupedOrderSheetView"""
|
in the DownloadGroupedOrderSheetView"""
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ class GroupedOrderSheetView(UserPassesTestMixin, generic.DetailView):
|
||||||
return self.get_object().orga == self.request.user
|
return self.get_object().orga == self.request.user
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(GroupedOrderSheetView, self).get_context_data(**kwargs)
|
context = super(GroupedOrderExportView, self).get_context_data(**kwargs)
|
||||||
grouped_order = self.get_object()
|
grouped_order = self.get_object()
|
||||||
|
|
||||||
# Get ordered items
|
# Get ordered items
|
||||||
|
@ -268,7 +268,7 @@ class GroupedOrderSheetView(UserPassesTestMixin, generic.DetailView):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class DownloadGroupedOrderSheetView(WeasyTemplateResponseMixin, GroupedOrderSheetView):
|
class DownloadGroupedOrderSheetView(WeasyTemplateResponseMixin, GroupedOrderExportView):
|
||||||
"""View for downloading the grouped order sheet,
|
"""View for downloading the grouped order sheet,
|
||||||
using django-weasyprint : https://pypi.org/project/django-weasyprint/"""
|
using django-weasyprint : https://pypi.org/project/django-weasyprint/"""
|
||||||
|
|
||||||
|
@ -278,8 +278,7 @@ class DownloadGroupedOrderSheetView(WeasyTemplateResponseMixin, GroupedOrderShee
|
||||||
|
|
||||||
|
|
||||||
class ExportGroupedOrderEmailAddressesToCSVView(UserPassesTestMixin, generic.View):
|
class ExportGroupedOrderEmailAddressesToCSVView(UserPassesTestMixin, generic.View):
|
||||||
# grouped_order_id = self.kwargs.get("grouped_order_id")
|
"""Export all participant email addresses in a csv line"""
|
||||||
# grouped_order = get_object_or_404(GroupedOrder, pk=grouped_order_id)
|
|
||||||
|
|
||||||
def test_func(self):
|
def test_func(self):
|
||||||
"""Accessible only if the requesting user is the grouped order organizer"""
|
"""Accessible only if the requesting user is the grouped order organizer"""
|
||||||
|
@ -303,3 +302,53 @@ class ExportGroupedOrderEmailAddressesToCSVView(UserPassesTestMixin, generic.Vie
|
||||||
row = [participant.email for participant in participants]
|
row = [participant.email for participant in participants]
|
||||||
writer.writerow(row)
|
writer.writerow(row)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class ExportGroupedOrderToCSVView(GroupedOrderExportView):
|
||||||
|
"""Export a csv with the same info as in pdf sheet"""
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
super(ExportGroupedOrderToCSVView, self).get(self, request, *args, **kwargs)
|
||||||
|
context = self.get_context_data()
|
||||||
|
|
||||||
|
response = http.HttpResponse(
|
||||||
|
content_type="text/csv",
|
||||||
|
headers={
|
||||||
|
"Content-Disposition": f'attachment; filename="{ context["object"].name }-commandes"'
|
||||||
|
},
|
||||||
|
)
|
||||||
|
writer = csv.writer(response)
|
||||||
|
|
||||||
|
# write headers rows
|
||||||
|
row = [""]
|
||||||
|
for item in context["items"]:
|
||||||
|
row.append(item.name)
|
||||||
|
row.append("Prix de la commande")
|
||||||
|
row.append("Mail")
|
||||||
|
row.append("Téléphone")
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
row = ["Prix unitaire (€)"]
|
||||||
|
for item in context["items"]:
|
||||||
|
row.append(str(item.price).replace(".", ","))
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
# write ordered values rows
|
||||||
|
for order, ordered_items in context["orders_dict"].items():
|
||||||
|
row = [order.author]
|
||||||
|
for ordered_nb in ordered_items:
|
||||||
|
row.append(ordered_nb)
|
||||||
|
row.append(str(order.price).replace(".", ","))
|
||||||
|
row.append(order.author.email)
|
||||||
|
row.append(f"'{order.author.phone}")
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
# write total row
|
||||||
|
|
||||||
|
row = ["TOTAL"]
|
||||||
|
for item in context["items"]:
|
||||||
|
row.append(item.ordered_nb)
|
||||||
|
row.append(str(context["object"].total_price).replace(".", ","))
|
||||||
|
writer.writerow(row)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
Loading…
Reference in a new issue