separate views into several files

This commit is contained in:
Laetitia Getti 2023-07-04 11:39:45 +02:00
parent 4f98a5ec88
commit f32987457d
4 changed files with 166 additions and 160 deletions

View file

@ -0,0 +1,10 @@
# fmt: off
from .grouped_order import (ExportGroupedOrderEmailAddressesToCSVView,
GroupedOrderAddItemsView, GroupedOrderCreateView,
GroupedOrderDetailView, GroupedOrderOverview,
GroupedOrderSheetView, GroupedOrderUpdateView,
IndexView)
from .item import ItemCreateView, ItemDeleteView
from .order import OrderDetailView, order
# fmt: on

View file

@ -3,16 +3,15 @@ from io import BytesIO
from django import http
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.core.exceptions import ValidationError
from django.shortcuts import get_object_or_404, render
from django.shortcuts import get_object_or_404
from django.template.loader import get_template
from django.urls import reverse, reverse_lazy
from django.urls import reverse
from django.utils import timezone
from django.views import generic
from xhtml2pdf import pisa
from .forms import GroupedOrderForm, ItemCreateForm
from .models import GroupedOrder, Item, Order, OrderAuthor, OrderedItem
from ..forms import GroupedOrderForm, Item
from ..models import GroupedOrder, OrderAuthor
class IndexView(LoginRequiredMixin, generic.ListView):
@ -148,146 +147,6 @@ class GroupedOrderAddItemsView(UserPassesTestMixin, generic.ListView):
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
class ItemCreateView(UserPassesTestMixin, generic.CreateView):
"""CreateView for an item"""
model = Item
form_class = ItemCreateForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["grouped_order"] = GroupedOrder.objects.get(id=self.kwargs.get("pk"))
return kwargs
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
grouped_order_id = self.kwargs.get("pk")
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
class ItemDeleteView(UserPassesTestMixin, generic.DeleteView):
"""DeleteView for an item
The form does a GET to this view - it displays a confirmation page - then we post this view
"""
model = Item
def get_success_url(self):
return reverse_lazy("order:manage_items", args=[self.object.grouped_order.id])
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
return self.get_object().grouped_order.orga == self.request.user
def order(request, grouped_order_id):
"""Creates an AnonymousUser, and an Order for this GroupedOrder, with related OrderedItems"""
grouped_order = get_object_or_404(GroupedOrder, pk=grouped_order_id)
# check if the grouped order is ongoing
if not grouped_order.is_ongoing():
return http.HttpResponseForbidden()
# get a dict with quantity_{{item_id}}:[ {{ quantity on phone }},{{ quantity on desktop }} ]
orders_dict = {
key: request.POST.getlist(key)
for key, value in request.POST.items()
if key.startswith("quantity")
}
# transform it into quantity_{{item_id}}: {{ greatest of the two quantities }}
for i in orders_dict:
value = (
orders_dict[i][0]
if orders_dict[i][0] >= orders_dict[i][1]
else orders_dict[i][1]
)
orders_dict[i] = value
# create an order
first_name = request.POST["first_name"]
last_name = request.POST["last_name"]
phone = request.POST["phone"]
email = request.POST["email"]
author = OrderAuthor.objects.create(
first_name=first_name, last_name=last_name, email=email, phone=phone
)
order = Order.objects.create(author=author, grouped_order=grouped_order)
# add items to the order
error_message = None
for key, quantity in orders_dict.items():
quantity = int(quantity)
item = grouped_order.item_set.get(pk=key.split("_")[1])
# check if too many items are ordered
error_message = validate_item_ordered_nb(item, quantity)
if error_message:
break # stop creating items if there is an error
if quantity > 0:
OrderedItem.objects.create(nb=quantity, order=order, item=item)
# Redisplay the form with error messages if there is an error
if error_message:
order.delete()
author.delete()
grouped_order.compute_items_ordered_nb()
return render(
request,
"order/grouped_order_detail.html",
{
"grouped_order": grouped_order,
"error_message": error_message,
},
)
# check if the order contains articles
error_message = validate_articles_ordered_nb(order)
# Redisplay the form with error messages if there is an error
if error_message:
order.delete()
author.delete()
return render(
request,
"order/grouped_order_detail.html",
{
"grouped_order": grouped_order,
"error_message": error_message,
},
)
# Redirect to confirmation page
order.compute_order_price()
grouped_order.compute_items_ordered_nb()
# Always return an http.HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return http.HttpResponseRedirect(
reverse("order:order_confirm", args=(grouped_order.pk, order.pk))
)
def validate_item_ordered_nb(item, ordered_nb):
"""Returns an error message if the ordered items are not available"""
if item.get_remaining_nb() is not None and item.get_remaining_nb() - ordered_nb < 0:
return f"Trop de {item.name} commandés pour la quantité disponible"
return None
def validate_articles_ordered_nb(order):
"""Return an error if no items are ordered"""
order.compute_order_articles_nb()
if order.articles_nb == 0:
return "Veuillez commander au moins un produit"
return None
class OrderDetailView(generic.DetailView):
"""Confirmation page after a user orders"""
model = Order
class GroupedOrderSheetMixin:
"""Mixin for grouped order info export (pdf sheet and csv)"""
@ -361,18 +220,3 @@ class ExportGroupedOrderEmailAddressesToCSVView(UserPassesTestMixin, generic.Vie
row = [participant.email for participant in participants]
writer.writerow(row)
return response
# def export_grouped_order_email_addresses_to_csv(request, grouped_order_id):
# """Exports a csv list of participants email addresses - only for the organizer"""
# # Check if the user is orga
# if request.user
# grouped_order = get_object_or_404(GroupedOrder, pk=grouped_order_id)
# participants = OrderAuthor.objects.filter(order__in=grouped_order.order_set.all())
# response = http.HttpResponse(content_type="text/csv", headers={'Content-Disposition': f'attachment; filename="{ grouped_order.name }-mails.csv"'},)
# writer = csv.writer(response)
# row = [participant.email for participant in participants]
# writer.writerow(row)
# return response

View file

@ -0,0 +1,38 @@
from django.contrib.auth.mixins import UserPassesTestMixin
from django.urls import reverse_lazy
from django.views import generic
from ..forms import ItemCreateForm
from ..models import GroupedOrder, Item
class ItemCreateView(UserPassesTestMixin, generic.CreateView):
"""CreateView for an item"""
model = Item
form_class = ItemCreateForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["grouped_order"] = GroupedOrder.objects.get(id=self.kwargs.get("pk"))
return kwargs
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
grouped_order_id = self.kwargs.get("pk")
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
class ItemDeleteView(UserPassesTestMixin, generic.DeleteView):
"""DeleteView for an item
The form does a GET to this view - it displays a confirmation page - then we post this view
"""
model = Item
def get_success_url(self):
return reverse_lazy("order:manage_items", args=[self.object.grouped_order.id])
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
return self.get_object().grouped_order.orga == self.request.user

View file

@ -0,0 +1,114 @@
from django import http
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from ..models import GroupedOrder, Order, OrderAuthor, OrderedItem
def order(request, grouped_order_id):
"""Creates an AnonymousUser, and an Order for this GroupedOrder, with related OrderedItems"""
grouped_order = get_object_or_404(GroupedOrder, pk=grouped_order_id)
# check if the grouped order is ongoing
if not grouped_order.is_ongoing():
return http.HttpResponseForbidden()
# get a dict with quantity_{{item_id}}:[ {{ quantity on phone }},{{ quantity on desktop }} ]
orders_dict = {
key: request.POST.getlist(key)
for key, value in request.POST.items()
if key.startswith("quantity")
}
# transform it into quantity_{{item_id}}: {{ greatest of the two quantities }}
for i in orders_dict:
value = (
orders_dict[i][0]
if orders_dict[i][0] >= orders_dict[i][1]
else orders_dict[i][1]
)
orders_dict[i] = value
# create an order
first_name = request.POST["first_name"]
last_name = request.POST["last_name"]
phone = request.POST["phone"]
email = request.POST["email"]
author = OrderAuthor.objects.create(
first_name=first_name, last_name=last_name, email=email, phone=phone
)
order = Order.objects.create(author=author, grouped_order=grouped_order)
# add items to the order
error_message = None
for key, quantity in orders_dict.items():
quantity = int(quantity)
item = grouped_order.item_set.get(pk=key.split("_")[1])
# check if too many items are ordered
error_message = validate_item_ordered_nb(item, quantity)
if error_message:
break # stop creating items if there is an error
if quantity > 0:
OrderedItem.objects.create(nb=quantity, order=order, item=item)
# Redisplay the form with error messages if there is an error
if error_message:
order.delete()
author.delete()
grouped_order.compute_items_ordered_nb()
return render(
request,
"order/grouped_order_detail.html",
{
"grouped_order": grouped_order,
"error_message": error_message,
},
)
# check if the order contains articles
error_message = validate_articles_ordered_nb(order)
# Redisplay the form with error messages if there is an error
if error_message:
order.delete()
author.delete()
return render(
request,
"order/grouped_order_detail.html",
{
"grouped_order": grouped_order,
"error_message": error_message,
},
)
# Redirect to confirmation page
order.compute_order_price()
grouped_order.compute_items_ordered_nb()
# Always return an http.HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return http.HttpResponseRedirect(
reverse("order:order_confirm", args=(grouped_order.pk, order.pk))
)
def validate_item_ordered_nb(item, ordered_nb):
"""Returns an error message if the ordered items are not available"""
if item.get_remaining_nb() is not None and item.get_remaining_nb() - ordered_nb < 0:
return f"Trop de {item.name} commandés pour la quantité disponible"
return None
def validate_articles_ordered_nb(order):
"""Return an error if no items are ordered"""
order.compute_order_articles_nb()
if order.articles_nb == 0:
return "Veuillez commander au moins un produit"
return None
class OrderDetailView(generic.DetailView):
"""Confirmation page after a user orders"""
model = Order