mirror of
https://framagit.org/la-chariotte/la-chariotte.git
synced 2025-05-02 11:52:27 +02:00
143 lines
4.7 KiB
Python
143 lines
4.7 KiB
Python
from django import http
|
|
from django.contrib.auth.mixins import UserPassesTestMixin
|
|
from django.shortcuts import get_object_or_404, render
|
|
from django.urls import reverse, reverse_lazy
|
|
from django.views import generic
|
|
|
|
from la_chariotte.mail.utils import send_order_confirmation_mail
|
|
|
|
from ..models import GroupedOrder, Order, OrderAuthor, OrderedItem
|
|
|
|
|
|
def place_order(request, code):
|
|
# Creates an AnonymousUser and an Order with related OrderedItems
|
|
grouped_order = get_object_or_404(GroupedOrder, code=code)
|
|
|
|
# Handle permissions
|
|
user_is_orga = request.user == grouped_order.orga
|
|
is_to_be_delivered = grouped_order.is_to_be_delivered()
|
|
is_open = grouped_order.is_open()
|
|
|
|
access_allowed = is_open or (user_is_orga and is_to_be_delivered)
|
|
|
|
if not access_allowed:
|
|
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"]
|
|
note = request.POST["note"]
|
|
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, note=note)
|
|
|
|
# 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,
|
|
"note": order.note,
|
|
"author": author,
|
|
},
|
|
)
|
|
|
|
# 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,
|
|
"note": order.note,
|
|
"author": author,
|
|
},
|
|
)
|
|
|
|
# Send confirmation mail and redirect to confirmation page
|
|
order.compute_order_price()
|
|
grouped_order.compute_items_ordered_nb()
|
|
send_order_confirmation_mail(order)
|
|
|
|
# Redirect to prevent data from being posted twice when the user hits the Back
|
|
# button.
|
|
return http.HttpResponseRedirect(
|
|
reverse("order:order_confirm", args=(grouped_order.code, 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):
|
|
model = Order
|
|
|
|
|
|
class OrderDeleteView(UserPassesTestMixin, generic.DeleteView):
|
|
model = Order
|
|
|
|
def get_success_url(self):
|
|
return reverse_lazy(
|
|
"order:grouped_order_overview", args=[self.object.grouped_order.code]
|
|
)
|
|
|
|
def test_func(self):
|
|
# Restrict access to the manager or a superuser
|
|
return (
|
|
self.get_object().grouped_order.orga == self.request.user
|
|
or self.request.user.is_superuser
|
|
)
|