From 25d0ef560429701847ea8b1979995b53f0abdb30 Mon Sep 17 00:00:00 2001 From: Laetitia Getti Date: Fri, 28 Jul 2023 15:19:19 +0200 Subject: [PATCH] csv export of a grouped order --- .../order/grouped_order_overview.html | 12 ++- .../test_views/test_views_grouped_order.py | 86 ++++++++++++++++++- la_chariotte/order/urls.py | 5 ++ la_chariotte/order/views/__init__.py | 5 +- la_chariotte/order/views/grouped_order.py | 59 +++++++++++-- 5 files changed, 152 insertions(+), 15 deletions(-) diff --git a/la_chariotte/order/templates/order/grouped_order_overview.html b/la_chariotte/order/templates/order/grouped_order_overview.html index 6f11842..45e6429 100644 --- a/la_chariotte/order/templates/order/grouped_order_overview.html +++ b/la_chariotte/order/templates/order/grouped_order_overview.html @@ -59,14 +59,14 @@
  • Partager - Partager et imprimer + Partager et exporter
  • -

    Partager et imprimer

    +

    Partager et exporter

    {% if not grouped_order.is_to_be_delivered %} @@ -87,9 +87,13 @@ {% endif %}
    -

    Pour vous aider à distribuer les produits le jour J, vous pouvez imprimer la liste des commandes :

    +

    Pour vous aider à distribuer les produits le jour J, vous pouvez télécharger la liste des commandes + au format PDF pour l'imprimer, ou au format CSV pour l'afficher dans un tableur :

    - Liste des commandes + Commandes en PDF + + + Commandes en CSV
    diff --git a/la_chariotte/order/tests/test_views/test_views_grouped_order.py b/la_chariotte/order/tests/test_views/test_views_grouped_order.py index e6e6bed..8235f02 100644 --- a/la_chariotte/order/tests/test_views/test_views_grouped_order.py +++ b/la_chariotte/order/tests/test_views/test_views_grouped_order.py @@ -1288,7 +1288,7 @@ class TestGroupedOrderSheetView: class TestExportGroupedOrderEmailAddressesToCSVView: 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( days_before_delivery_date=5, @@ -1310,7 +1310,7 @@ class TestExportGroupedOrderEmailAddressesToCSVView: 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 """ grouped_order = create_grouped_order( @@ -1328,9 +1328,9 @@ class TestExportGroupedOrderEmailAddressesToCSVView: response = client_log.get(email_list_view_url) 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( days_before_delivery_date=5, @@ -1352,3 +1352,81 @@ class TestExportGroupedOrderEmailAddressesToCSVView: response = client_log.get(email_list_view_url) assert response.status_code == 200 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() diff --git a/la_chariotte/order/urls.py b/la_chariotte/order/urls.py index dc1706e..7608be5 100644 --- a/la_chariotte/order/urls.py +++ b/la_chariotte/order/urls.py @@ -65,4 +65,9 @@ urlpatterns = [ views.ExportGroupedOrderEmailAddressesToCSVView.as_view(), name="email_list", ), + path( + "/gerer/csv", + views.ExportGroupedOrderToCSVView.as_view(), + name="grouped_order_csv_export", + ), ] diff --git a/la_chariotte/order/views/__init__.py b/la_chariotte/order/views/__init__.py index 0307e86..4578d45 100644 --- a/la_chariotte/order/views/__init__.py +++ b/la_chariotte/order/views/__init__.py @@ -1,10 +1,11 @@ # fmt: off from .grouped_order import (DownloadGroupedOrderSheetView, ExportGroupedOrderEmailAddressesToCSVView, + ExportGroupedOrderToCSVView, GroupedOrderAddItemsView, GroupedOrderCreateView, GroupedOrderDeleteView, GroupedOrderDetailView, - GroupedOrderDuplicateView, GroupedOrderOverview, - GroupedOrderSheetView, GroupedOrderUpdateView, + GroupedOrderDuplicateView, GroupedOrderExportView, + GroupedOrderOverview, GroupedOrderUpdateView, IndexView) from .item import ItemCreateView, ItemDeleteView from .order import OrderDeleteView, OrderDetailView, place_order diff --git a/la_chariotte/order/views/grouped_order.py b/la_chariotte/order/views/grouped_order.py index e121b8c..b348204 100644 --- a/la_chariotte/order/views/grouped_order.py +++ b/la_chariotte/order/views/grouped_order.py @@ -229,7 +229,7 @@ class GroupedOrderAddItemsView(UserPassesTestMixin, generic.ListView): 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 in the DownloadGroupedOrderSheetView""" @@ -242,7 +242,7 @@ class GroupedOrderSheetView(UserPassesTestMixin, generic.DetailView): return self.get_object().orga == self.request.user 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() # Get ordered items @@ -268,7 +268,7 @@ class GroupedOrderSheetView(UserPassesTestMixin, generic.DetailView): return context -class DownloadGroupedOrderSheetView(WeasyTemplateResponseMixin, GroupedOrderSheetView): +class DownloadGroupedOrderSheetView(WeasyTemplateResponseMixin, GroupedOrderExportView): """View for downloading the grouped order sheet, using django-weasyprint : https://pypi.org/project/django-weasyprint/""" @@ -278,8 +278,7 @@ class DownloadGroupedOrderSheetView(WeasyTemplateResponseMixin, GroupedOrderShee class ExportGroupedOrderEmailAddressesToCSVView(UserPassesTestMixin, generic.View): - # grouped_order_id = self.kwargs.get("grouped_order_id") - # grouped_order = get_object_or_404(GroupedOrder, pk=grouped_order_id) + """Export all participant email addresses in a csv line""" def test_func(self): """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] writer.writerow(row) 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