1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-11-01 16:14:30 +01:00

Alpha version (without tests)

This commit is contained in:
Ehouarn
2025-10-30 23:54:23 +01:00
parent d4cb464169
commit 6bf21b103f
24 changed files with 1229 additions and 14 deletions

View File

@@ -4,25 +4,30 @@
from datetime import timedelta
from api.viewsets import is_regex
from django_tables2.views import MultiTableMixin
from crispy_forms.helper import FormHelper
from django_tables2.views import SingleTableView, MultiTableMixin
from django.core.exceptions import PermissionDenied
from django.db import transaction
from django.db.models import Q
from django.http import HttpResponseRedirect, Http404
from django.views.generic import DetailView, UpdateView, CreateView
from django.views.generic.list import ListView
from django.views.generic.base import RedirectView
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from member.models import Club, Membership
from activity.models import Activity
from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin, ProtectedCreateView, LoginRequiredMixin
from .models import Food, BasicFood, TransformedFood, QRCode
from .models import Food, BasicFood, TransformedFood, QRCode, Order, Dish
from .forms import QRCodeForms, BasicFoodForms, TransformedFoodForms, \
ManageIngredientsForm, ManageIngredientsFormSet, AddIngredientForms, \
BasicFoodUpdateForms, TransformedFoodUpdateForms
from .tables import FoodTable
BasicFoodUpdateForms, TransformedFoodUpdateForms, \
DishForm, SupplementFormSet, SupplementFormSetHelper, OrderForm
from .tables import FoodTable, DishTable, OrderTable
from .utils import pretty_duration
@@ -112,6 +117,9 @@ class FoodListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, Li
context['club_tables'] = tables[3:]
context['can_add_meal'] = PermissionBackend.check_perm(self.request, 'food.transformedfood_add')
context["open_activities"] = Activity.objects.filter(activity_type__name="Perm bouffe", open=True)
return context
@@ -526,3 +534,270 @@ class QRCodeRedirectView(RedirectView):
if slug:
return reverse_lazy('food:qrcode_create', kwargs={'slug': slug})
return reverse_lazy('food:list')
class DishCreateView(ProtectQuerysetMixin, ProtectedCreateView):
"""
Create a dish
"""
model = Dish
form_class = DishForm
extra_context = {"title": _('Create dish')}
def get_sample_object(self):
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
sample_food = TransformedFood(
name="Sample food",
owner=activity.organizer,
expiry_date=timezone.now() + timedelta(days=7),
is_ready=True,
)
sample_dish = Dish(
main=sample_food,
price=100,
activity=activity,
)
return sample_dish
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
form = context['form']
form.helper = FormHelper()
# Remove form tag on the generation of the form in the template (already present on the template)
form.helper.form_tag = False
# The formset handles the set of the supplements
form_set = SupplementFormSet(instance=form.instance)
context['formset'] = form_set
context['helper'] = SupplementFormSetHelper()
return context
def get_form(self, form_class=None):
form = super().get_form(form_class)
if "available" in form.fields:
del form.fields["available"]
return form
@transaction.atomic
def form_valid(self, form):
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
form.instance.activity = activity
ret = super().form_valid(form)
# For each supplement, we save it
formset = SupplementFormSet(self.request.POST, instance=form.instance)
if formset.is_valid():
for f in formset:
if f.is_valid():
f.save()
f.instance.save()
else:
f.instance = None
return ret
def get_success_url(self):
return reverse_lazy('food:dish_list', kwargs={"activity_pk": self.kwargs["activity_pk"]})
class DishListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
"""
List dishes for this activity
"""
model = Dish
table_class = DishTable
extra_context = {"title": _('Dishes served during')}
template_name = 'food/dish_list.html'
def get_queryset(self):
return super().get_queryset().filter(activity__pk=self.kwargs["activity_pk"])
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
context["activity"] = activity
context["can_add_dish"] = PermissionBackend.check_perm(self.request, 'food.dish_add')
return context
class DishDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
"""
View a dish for this activity
"""
model = Dish
extra_context = {"title": _('Details of:')}
context_oject_name = "dish"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["food"] = self.object.main
context["supplements"] = self.object.supplements.all()
context["update"] = PermissionBackend.check_perm(self.request, "food.change_dish")
context["delete"] = not Order.objects.filter(dish=self.get_object()).exists() and PermissionBackend.check_perm(self.request, "food.delete_dish")
return context
class DishUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
"""
A view to update a dish
"""
model = Dish
form_class = DishForm
extra_context = {"title": _("Update a dish")}
def get_form(self, **kwargs):
form = super().get_form(**kwargs)
if 'main' in form.fields:
del form.fields["main"]
return form
class DishDeleteView(ProtectQuerysetMixin, LoginRequiredMixin, DeleteView):
"""
Delete a dish with no order yet
"""
model = Dish
extra_context = {"title": _('Delete dish')}
def delete(self, request, *args, **kwargs):
if Order.objects.filter(dish=self.get_object()).exists():
raise PermissionDenied(_("This dish cannot be deleted because it has already been ordered"))
return super().delete(request, *args, **kwargs)
def get_success_url(self):
return reverse_lazy('food:dish_list', kwargs={"activity_pk": self.kwargs["activity_pk"]})
class OrderCreateView(ProtectQuerysetMixin, ProtectedCreateView):
"""
Order a meal
"""
model = Order
form_class = OrderForm
extra_context = {"title": _('Order food')}
def get_sample_object(self):
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
sample_order = Order(
user=self.request.user,
activity=activity,
dish=Dish.objects.filter(activity=activity).last(),
)
return sample_order
def get_form(self):
form = super().get_form()
form.fields["user"].initial = self.request.user
form.fields["user"].disabled = True
return form
def form_valid(self, form):
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
form.instance.activity = activity
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('food:food_list')
class OrderListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView):
"""
List existing Families
"""
model = Order
table_class = OrderTable
extra_context = {"title": _('Order list')}
paginate_by = 10
def get_queryset(self, **kwargs):
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
return Order.objects.filter(activity=activity)
def get_tables(self):
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
dishes = Dish.objects.filter(activity=activity)
tables = [OrderTable] * dishes.count()
self.tables = tables
tables = super().get_tables()
for i in range(dishes.count()):
tables[i].prefix = dishes[i].main.name
return tables
def get_tables_data(self):
activity = Activity.objects.get(pk=self.kwargs["activity_pk"])
dishes = Dish.objects.filter(activity=activity)
tables = []
for dish in dishes:
tables.append(self.get_queryset().order_by('ordered_at').filter(
dish=dish, served=False).filter(
PermissionBackend.filter_queryset(self.request, Order, 'view')
))
return tables
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["activity"] = Activity.objects.get(pk=self.kwargs["activity_pk"])
return context
class ServedOrderListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
"""
View served orders
"""
model = Order
template_name = 'food/served_order_list.html'
table_class = OrderTable
def get_queryset(self):
return super().get_queryset().filter(activity__pk=self.kwargs["activity_pk"], served=True).order_by('-served_at')
def get_table(self, **kwargs):
table = super().get_table(**kwargs)
table.columns.hide("delete")
return table
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["activity"] = Activity.objects.get(pk=self.kwargs["activity_pk"])
return context
class OrderDeleteView(ProtectQuerysetMixin, LoginRequiredMixin, DeleteView):
"""
Delete an order
"""
model = Order
extra_context = {"title": _('Delete dish')}
def delete(self, request, *args, **kwargs):
if self.get_object().served:
raise PermissionDenied(_("This order cannot be deleted because it has already been served"))
return super().delete(request, *args, **kwargs)
def get_success_url(self):
return reverse_lazy('food:order_list', kwargs={"activity_pk": self.kwargs["activity_pk"]})