# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.db import transaction from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpResponseRedirect from django_tables2.views import MultiTableMixin from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.utils import timezone from django.views.generic import DetailView, UpdateView, TemplateView from django.views.generic.list import ListView from permission.backends import PermissionBackend from permission.views import ProtectQuerysetMixin, ProtectedCreateView from member.models import Club from note_kfet.middlewares import get_current_request from .forms import AddIngredientForms, BasicFoodForms, QRCodeForms, TransformedFoodForms from .models import BasicFood, Food, QRCode, TransformedFood from .tables import TransformedFoodTable class AddIngredientView(ProtectQuerysetMixin, UpdateView): """ A view to add an ingredient """ model = Food template_name = 'food/add_ingredient_form.html' extra_context = {"title": _("Add the ingredient")} form_class = AddIngredientForms def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["pk"] = self.kwargs["pk"] return context @transaction.atomic def form_valid(self, form): form.instance.creater = self.request.user food = Food.objects.get(pk=self.kwargs['pk']) add_ingredient_form = AddIngredientForms(data=self.request.POST) if not food.is_ready: form.add_error(None, _("The product isn't ready")) return self.form_invalid(form) if not add_ingredient_form.is_valid(): return self.form_invalid(form) # Save the aliment and the allergens associed for transformed_pk in self.request.POST.getlist('ingredient'): transformed = TransformedFood.objects.get(pk=transformed_pk) if not transformed.is_ready: transformed.ingredient.add(food) transformed.update() return HttpResponseRedirect(self.get_success_url()) def get_success_url(self, **kwargs): return reverse('food:food_list') class BasicFoodUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView): """ A view to add a basic food """ model = BasicFood form_class = BasicFoodForms template_name = 'food/basic_food_form.html' extra_context = {"title": _("Add a new aliment")} @transaction.atomic def form_valid(self, form): form.instance.creater = self.request.user basic_food_form = BasicFoodForms(data=self.request.POST) if not basic_food_form.is_valid(): return self.form_invalid(form) ans = super().form_valid(form) form.instance.update() return ans def get_success_url(self, **kwargs): self.object.refresh_from_db() return reverse('food:food_view', kwargs={"pk": self.object.pk}) class FoodCreateView(ProtectQuerysetMixin, LoginRequiredMixin, TemplateView): """ A view to add a new aliment """ template_name = 'food/create_food_form.html' extra_context = {"title": _("Add a new aliment")} class FoodView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): """ A view to see a food """ model = Food extra_context = {"title": _("Details")} context_object_name = "food" class QRCodeBasicFoodCreateView(ProtectQuerysetMixin, ProtectedCreateView): ##################################################################### # TO DO # - fix picture save # - implement solution crop and convert image (reuse or recode ImageForm from members apps) ##################################################################### """ A view to add a basic food with a qrcode """ model = BasicFood form_class = BasicFoodForms template_name = 'food/basic_food_form.html' extra_context = {"title": _("Add a new basic food with QRCode")} @transaction.atomic def form_valid(self, form): form.instance.creater = self.request.user basic_food_form = BasicFoodForms(data=self.request.POST) if not basic_food_form.is_valid(): return self.form_invalid(form) # Save the aliment and the allergens associed basic_food = form.save(commit=False) # We assume the date of labeling and the same as the date of arrival basic_food.arrival_date = timezone.now() basic_food.is_ready = True basic_food._force_save = True basic_food.save() basic_food.refresh_from_db() qrcode = QRCode() qrcode.qr_code_number = self.kwargs['slug'] qrcode.food_container = basic_food qrcode.save() return super().form_valid(form) def get_success_url(self, **kwargs): self.object.refresh_from_db() return reverse('food:qrcode_view', kwargs={"slug": self.kwargs['slug']}) def get_sample_object(self): return BasicFood( name="", expiry_date=timezone.now(), ) class QRCodeCreateView(ProtectQuerysetMixin, ProtectedCreateView): """ A view to add a new qrcode """ model = QRCode template_name = 'food/create_qrcode_form.html' form_class = QRCodeForms extra_context = {"title": _("Add a new QRCode")} def get(self, *args, **kwargs): qrcode = kwargs["slug"] if self.model.objects.filter(qr_code_number=qrcode).count() > 0: return HttpResponseRedirect(reverse("food:qrcode_view", kwargs=kwargs)) else: return super().get(*args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["slug"] = self.kwargs["slug"] return context @transaction.atomic def form_valid(self, form): form.instance.creater = self.request.user qrcode_food_form = QRCodeForms(data=self.request.POST) if not qrcode_food_form.is_valid(): return self.form_invalid(form) # Save the qrcode qrcode = form.save(commit=False) qrcode.qr_code_number = self.kwargs["slug"] qrcode._force_save = True qrcode.save() qrcode.refresh_from_db() qrcode.food_container.is_ready = True qrcode.food_container.save() return super().form_valid(form) def get_success_url(self, **kwargs): self.object.refresh_from_db() return reverse('food:qrcode_view', kwargs={"slug": self.kwargs['slug']}) def get_sample_object(self): return QRCode( qr_code_number=self.kwargs["slug"], ) class QRCodeView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView): """ A view to see a qrcode """ model = QRCode extra_context = {"title": _("QRCode")} context_object_name = "qrcode" slug_field = "qr_code_number" def get(self, *args, **kwargs): qrcode = kwargs["slug"] if self.model.objects.filter(qr_code_number=qrcode).count() > 0: return super().get(*args, **kwargs) else: return HttpResponseRedirect(reverse("food:qrcode_create", kwargs=kwargs)) class TransformedFoodFormView(ProtectQuerysetMixin): """ A view to add a tranformed food """ model = TransformedFood template_name = 'food/transformed_food_form.html' form_class = TransformedFoodForms extra_context = {"title": _("Add a new meal")} @transaction.atomic def form_valid(self, form): form.instance.creater = self.request.user transformed_food_form = TransformedFoodForms(data=self.request.POST) if not transformed_food_form.is_valid(): return self.form_invalid(form) # Save the aliment and allergens associated transformed_food = form.save(commit=False) transformed_food.expiry_date = transformed_food.creation_date transformed_food._force_save = True transformed_food.save() transformed_food.refresh_from_db() ans = super().form_valid(form) transformed_food.update() return ans def get_success_url(self, **kwargs): self.object.refresh_from_db() return reverse('food:food_view', kwargs={"pk": self.object.pk}) class TransformedFoodUpdateView(TransformedFoodFormView, LoginRequiredMixin, UpdateView): pass class TransformedFoodCreateView(TransformedFoodFormView, ProtectedCreateView): def get_sample_object(self): return TransformedFood( name="", creation_date=timezone.now(), ) class TransformedListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView): """ Displays ready TransformedFood """ model = TransformedFood tables = [TransformedFoodTable, TransformedFoodTable, TransformedFoodTable] extra_context = {"title": _("Transformed food")} def get_queryset(self, **kwargs): return super().get_queryset(**kwargs).distinct() def get_tables(self): tables = super().get_tables() tables[0].prefix = "all-" tables[1].prefix = "open-" tables[2].prefix = "served-" return tables def get_tables_data(self): # first table = all transformed food, second table = free, third = served return [ self.get_queryset().order_by("-creation_date"), TransformedFood.objects.filter(is_ready=True,is_active=True,was_eaten=False,expiry_date__lt=timezone.now()) .filter(PermissionBackend.filter_queryset(self.request, TransformedFood, "view")) .distinct() .order_by("-creation_date"), TransformedFood.objects.filter(is_ready=True,is_active=True,was_eaten=False,expiry_date__gte=timezone.now()) .filter(PermissionBackend.filter_queryset(self.request, TransformedFood, "view")) .distinct() .order_by("-creation_date") ] def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # context["can_create_meal"] = PermissionBackend.check_perm(self.request, "food.add_transformedfood", TransformedFood(creation_date = timezone.now(), name = "", expiry_date = timezone.now(), owner = )) <- défi prendre un club qui fonctionne (s'il existe) pour l'utilisateur context["can_create_meal"] = True tables = context["tables"] for name, table in zip(["table", "open", "served"], tables): context[name] = table return context