Improve/modify form, view, template. Add permissions

This commit is contained in:
quark 2024-08-17 02:28:27 +02:00
parent 6d7076b03e
commit debeb33d46
11 changed files with 605 additions and 132 deletions

View File

@ -11,7 +11,7 @@ from note_kfet.inputs import Autocomplete, DateTimePickerInput
from note_kfet.middlewares import get_current_request from note_kfet.middlewares import get_current_request
from permission.backends import PermissionBackend from permission.backends import PermissionBackend
from .models import BasicFood, QRCode, TransformedFood, Food from .models import BasicFood, QRCode, TransformedFood
class AddIngredientForms(forms.ModelForm): class AddIngredientForms(forms.ModelForm):
@ -20,11 +20,20 @@ class AddIngredientForms(forms.ModelForm):
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['ingredient'].queryset = self.fields['ingredient'].queryset.filter(is_ready=False, is_active=True, was_eaten=False) self.fields['ingredient'].queryset = self.fields['ingredient'].queryset.filter(
polymorphic_ctype__model='transformedfood',
owner_id=self.instance.owner_id,
is_ready=False,
is_active=True,
was_eaten=False,
)
# Caution, the logic is inverted here, we flip the logic on saving in AddIngredientView
self.fields['is_active'].initial = True
self.fields['is_active'].label = _("Fully used")
class Meta: class Meta:
model = TransformedFood model = TransformedFood
fields = ('ingredient',) fields = ('ingredient', 'is_active')
class BasicFoodForms(forms.ModelForm): class BasicFoodForms(forms.ModelForm):
@ -38,7 +47,7 @@ class BasicFoodForms(forms.ModelForm):
self.fields['owner'].required = True self.fields['owner'].required = True
# Some example # Some example
self.fields['name'].widget.attrs.update({"placeholder": _("pasta")}) self.fields['name'].widget.attrs.update({"placeholder": _("Pasta METRO 5kg")})
clubs = list(Club.objects.filter(PermissionBackend.filter_queryset(get_current_request(), Club, "change")).all()) clubs = list(Club.objects.filter(PermissionBackend.filter_queryset(get_current_request(), Club, "change")).all())
shuffle(clubs) shuffle(clubs)
self.fields['owner'].widget.attrs["placeholder"] = ", ".join(club.name for club in clubs[:4]) + ", ..." self.fields['owner'].widget.attrs["placeholder"] = ", ".join(club.name for club in clubs[:4]) + ", ..."
@ -84,7 +93,7 @@ class TransformedFoodForms(forms.ModelForm):
self.fields['was_eaten'].initial = False self.fields['was_eaten'].initial = False
# Some example # Some example
self.fields['name'].widget.attrs.update({"placeholder": _("lasagna")}) self.fields['name'].widget.attrs.update({"placeholder": _("Lasagna")})
clubs = list(Club.objects.filter(PermissionBackend.filter_queryset(get_current_request(), Club, "change")).all()) clubs = list(Club.objects.filter(PermissionBackend.filter_queryset(get_current_request(), Club, "change")).all())
shuffle(clubs) shuffle(clubs)
self.fields['owner'].widget.attrs["placeholder"] = ", ".join(club.name for club in clubs[:4]) + ", ..." self.fields['owner'].widget.attrs["placeholder"] = ", ".join(club.name for club in clubs[:4]) + ", ..."
@ -99,13 +108,3 @@ class TransformedFoodForms(forms.ModelForm):
), ),
'creation_date': DateTimePickerInput(), 'creation_date': DateTimePickerInput(),
} }
class FoodForms(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['was_eaten'].initial = True
class Meta:
model = Food
fields = ('was_eaten',)

View File

@ -94,7 +94,6 @@ class Food(PolymorphicModel):
verbose_name=_('is active'), verbose_name=_('is active'),
) )
def __str__(self): def __str__(self):
return self.name return self.name
@ -176,6 +175,11 @@ class TransformedFood(Food):
default=timedelta(days=3), default=timedelta(days=3),
) )
@transaction.atomic
def archive(self):
# When a meal are archived, if it was eaten, update ingredient fully used for this meal
raise NotImplementedError
@transaction.atomic @transaction.atomic
def update_allergens(self): def update_allergens(self):
# When allergens are changed, simply update the parents' allergens # When allergens are changed, simply update the parents' allergens

View File

@ -7,21 +7,31 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% block content %} {% block content %}
<div class="card bg-white mb-3"> <div class="card bg-white mb-3">
<h3 class="card-header text-center"> <h3 class="card-header text-center">
HTML not finished <br> {{ title }} {{ food.name }}
{{ title }}
</h3> </h3>
<div class="card-body"> <div class="card-body">
<p>{% trans 'Name' %} : {{ food.name }}</p> <ul>
<p>{% trans 'Owner' %} : {{ food.owner }}</p> <li><p>{% trans 'Owner' %} : {{ food.owner }}</p></li>
<p>{% trans 'Arrival date' %} : {{ food.arrival_date }}</p> <li><p>{% trans 'Arrival date' %} : {{ food.arrival_date }}</p></li>
<p>{% trans 'Expiry date' %} : {{ food.expiry_date }}</p> <li><p>{% trans 'Expiry date' %} : {{ food.expiry_date }} ({{ food.date_type }})</p></li>
<p>{% trans 'Allergens' %} :</p> <li>{% trans 'Allergens' %} :</li>
<ul> <ul>
{% for allergen in food.allergens.iterator %} {% for allergen in food.allergens.iterator %}
<li>{{ allergen.name }}</li> <li>{{ allergen.name }}</li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href="{% url "food:basic_update" pk=food.pk %}">{% trans 'Update' %}</a> <p>
<li><p>{% trans 'Active' %} : {{ food.is_active }}<p></li>
<li><p>{% trans 'Eaten' %} : {{ food.was_eaten }}<p></li>
</ul>
{% if can_update %}
<a class="btn btn-sm btn-warning" href="{% url "food:basic_update" pk=food.pk %}">{% trans 'Update' %}</a>
{% endif %}
{% if can_add_ingredient %}
<a class="btn btn-sm btn-success" href="{% url "food:add_ingredient" pk=food.pk %}">
{% trans 'Add to a meal' %}
</a>
{% endif %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,21 +0,0 @@
{% extends "base.html" %}
{% comment %}
SPDX-License-Identifier: GPL-3.0-or-later
{% endcomment %}
{% block content %}
<div class="card bg-white mb-3">
<h3 class="card-header text-center">
HTML not finished <br>
{{ title }}
</h3>
<div class="row">
<div class="col-xl-12">
<div class="btn-group btn-block">
<a href="{% url "food:basic_create" %}" class="btn btn-sm btn-outline-primary">Basic</a>
<a href="{% url "food:transformed_create" %}" class="btn btn-sm btn-outline-primary">Transformed</a>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -7,17 +7,16 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% block content %} {% block content %}
<div class="card bg-white mb-3"> <div class="card bg-white mb-3">
<h3 class="card-header text-center"> <h3 class="card-header text-center">
HTML not finished <br>
{{ title }} {{ title }}
</h3> </h3>
<div class="card-body" id="form"> <div class="card-body" id="form">
<a class="btn btn-sm btn-success" href="{% url "food:qrcode_basic_create" slug=slug %}" data-turbolinks="false"> <a class="btn btn-sm btn-success" href="{% url "food:qrcode_basic_create" slug=slug %}">
New basic food {% trans 'New basic food' %}
</a> </a>
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}
<button class="btn btn-primary" type="submit">{% trans "Submit"%}</button> <button class="btn btn-primary" type="submit">{% trans "Submit" %}</button>
</form> </form>
</div> </div>
</div> </div>

View File

@ -7,14 +7,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% block content %} {% block content %}
<div class="card bg-white mb-3"> <div class="card bg-white mb-3">
<h3 class="card-header text-center"> <h3 class="card-header text-center">
HTML finished <br> {{ title }} {% trans 'number' %} {{ qrcode.qr_code_number }}
{{ title }}
</h3> </h3>
<div class="card-body"> <div class="card-body">
<p>{% trans 'QR-code number' %} : {{ qrcode.qr_code_number }}</p> <ul>
<p>{% trans 'Name' %} : {{ qrcode.food_container.name }}</p> <li><p>{% trans 'Name' %} : {{ qrcode.food_container.name }}</p></li>
<p>{% trans 'Owner' %} : {{ qrcode.food_container.owner }}</p> <li><p>{% trans 'Owner' %} : {{ qrcode.food_container.owner }}</p></li>
<p>{% trans 'Expiry date' %} : {{ qrcode.food_container.expiry_date }}</p> <li><p>{% trans 'Expiry date' %} : {{ qrcode.food_container.expiry_date }}</p></li>
</ul>
{% if qrcode.food_container.polymorphic_ctype.model == 'basicfood' and can_update_basic %} {% if qrcode.food_container.polymorphic_ctype.model == 'basicfood' and can_update_basic %}
<a class="btn btn-sm btn-warning" href="{% url "food:basic_update" pk=qrcode.food_container.pk %}" data-turbolinks="false"> <a class="btn btn-sm btn-warning" href="{% url "food:basic_update" pk=qrcode.food_container.pk %}" data-turbolinks="false">
{% trans 'Update' %} {% trans 'Update' %}
@ -24,9 +24,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% trans 'Update' %} {% trans 'Update' %}
</a> </a>
{% endif %} {% endif %}
{% if can_view_detail %}
<a class="btn btn-sm btn-primary" href="{% url "food:food_view" pk=qrcode.food_container.pk %}">
{% trans 'View details' %}
</a>
{% endif %}
{% if can_add_ingredient %} {% if can_add_ingredient %}
<a class="btn btn-sm btn-success" href="{% url "food:add_ingredient" pk=qrcode.food_container.pk %}"> <a class="btn btn-sm btn-success" href="{% url "food:add_ingredient" pk=qrcode.food_container.pk %}">
{% trans 'Add the ingredient' %} {% trans 'Add to a meal' %}
</a> </a>
{% endif %} {% endif %}
</div> </div>

View File

@ -7,27 +7,45 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% block content %} {% block content %}
<div class="card bg-white mb-3"> <div class="card bg-white mb-3">
<h3 class="card-header text-center"> <h3 class="card-header text-center">
HTML not finished <br> {{ title }} {{ food.name }}
{{ title }}
</h3> </h3>
<div class="card-body"> <div class="card-body">
<p>{% trans 'Name' %} : {{ food.name }}</p> <ul>
<p>{% trans 'Owner' %} : {{ food.owner }}</p> <li><p>{% trans 'Owner' %} : {{ food.owner }}</p></li>
<p>{% trans 'Creation date' %} : {{ food.creation_date }}</p> {% if can_see_ready %}
<p>{% trans 'Expiry date' %} : {{ food.expiry_date }}</p> <li><p>{% trans 'Ready' %} : {{ food.is_ready }}</p></li>
<p>{% trans 'Allergens' %} :</p> {% endif %}
<li><p>{% trans 'Creation date' %} : {{ food.creation_date }}</p></li>
<li><p>{% trans 'Expiry date' %} : {{ food.expiry_date }}</p></li>
<li>{% trans 'Allergens' %} :</li>
<ul> <ul>
{% for allergen in food.allergens.iterator %} {% for allergen in food.allergens.iterator %}
<li>{{ allergen.name }}</li> <li>{{ allergen.name }}</li>
{% endfor %} {% endfor %}
</ul> </ul>
<p>{% trans 'Ingredients' %} :</p> <p>
<li>{% trans 'Ingredients' %} :</li>
<ul> <ul>
{% for ingredient in food.ingredient.iterator %} {% for ingredient in food.ingredient.iterator %}
<li><a href="{% url "food:food_view" pk=ingredient.pk %}">{{ ingredient.name }}</a></li> <li><a href="{% url "food:food_view" pk=ingredient.pk %}">{{ ingredient.name }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href="{% url "food:transformed_update" pk=food.pk %}">{% trans 'Update' %}</a> <p>
<li><p>{% trans 'Shelf life' %} : {{ food.shelf_life }}</p></li>
<li><p>{% trans 'Ready' %} : {{ food.is_ready }}</p></li>
<li><p>{% trans 'Active' %} : {{ food.is_active }}</p></li>
<li><p>{% trans 'Eaten' %} : {{ food.was_eaten }}</p></li>
</ul>
{% if can_update %}
<a class="btn btn-sm btn-warning" href="{% url "food:transformed_update" pk=food.pk %}">
{% trans 'Update' %}
</a>
{% endif %}
{% if can_add_ingredient %}
<a class="btn btn-sm btn-success" href="{% url "food:add_ingredient" pk=food.pk %}">
{% trans 'Add to a meal' %}
</a>
{% endif %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -7,7 +7,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% block content %} {% block content %}
<div class="card bg-white mb-3"> <div class="card bg-white mb-3">
<h3 class="card-header text-center"> <h3 class="card-header text-center">
HTML not finished <br>
{{ title }} {{ title }}
</h3> </h3>
<div class="card-body" id="form"> <div class="card-body" id="form">

View File

@ -35,7 +35,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if open.data %} {% if open.data %}
{% render_table open %} {% render_table open %}
{% else %} {% else %}
<div> class="card-body"> <div class="card-body">
<div class="alert alert-warning"> <div class="alert alert-warning">
{% trans "There is no free meal." %} {% trans "There is no free meal." %}
</div> </div>
@ -50,7 +50,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% if table.data %} {% if table.data %}
{% render_table table %} {% render_table table %}
{% else %} {% else %}
<div> class="card-body"> <div class="card-body">
<div class="alert alert-warning"> <div class="alert alert-warning">
{% trans "There is no meal." %} {% trans "There is no meal." %}
</div> </div>

View File

@ -8,15 +8,13 @@ from django_tables2.views import MultiTableMixin
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils import timezone from django.utils import timezone
from django.views.generic import DetailView, UpdateView, TemplateView from django.views.generic import DetailView, UpdateView
from django.views.generic.list import ListView from django.views.generic.list import ListView
from django.forms import HiddenInput from django.forms import HiddenInput
from permission.backends import PermissionBackend from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin, ProtectedCreateView 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, FoodForms from .forms import AddIngredientForms, BasicFoodForms, QRCodeForms, TransformedFoodForms
from .models import BasicFood, Food, QRCode, TransformedFood from .models import BasicFood, Food, QRCode, TransformedFood
from .tables import TransformedFoodTable from .tables import TransformedFoodTable
@ -25,7 +23,6 @@ class AddIngredientView(ProtectQuerysetMixin, UpdateView):
""" """
A view to add an ingredient A view to add an ingredient
""" """
# TO DO : ajouter un champ fully_used dans le form et changer was_eaten en conséquence + mieux filtrer les plat dispo avec des perms
model = Food model = Food
template_name = 'food/add_ingredient_form.html' template_name = 'food/add_ingredient_form.html'
extra_context = {"title": _("Add the ingredient")} extra_context = {"title": _("Add the ingredient")}
@ -41,19 +38,22 @@ class AddIngredientView(ProtectQuerysetMixin, UpdateView):
form.instance.creater = self.request.user form.instance.creater = self.request.user
food = Food.objects.get(pk=self.kwargs['pk']) food = Food.objects.get(pk=self.kwargs['pk'])
add_ingredient_form = AddIngredientForms(data=self.request.POST) add_ingredient_form = AddIngredientForms(data=self.request.POST)
food_form = FoodForms(data=self.request.POST)
if food.is_ready: if food.is_ready:
form.add_error(None, _("The product is already prepared")) form.add_error(None, _("The product is already prepared"))
return self.form_invalid(form) return self.form_invalid(form)
if not add_ingredient_form.is_valid(): if not add_ingredient_form.is_valid():
return self.form_invalid(form) return self.form_invalid(form)
# We flip logic ""fully used = not is_active""
food.is_active = not food.is_active
# Save the aliment and the allergens associed # Save the aliment and the allergens associed
for transformed_pk in self.request.POST.getlist('ingredient'): for transformed_pk in self.request.POST.getlist('ingredient'):
transformed = TransformedFood.objects.get(pk=transformed_pk) transformed = TransformedFood.objects.get(pk=transformed_pk)
if not transformed.is_ready: if not transformed.is_ready:
transformed.ingredient.add(food) transformed.ingredient.add(food)
transformed.update() transformed.update()
food.save()
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())
def get_success_url(self, **kwargs): def get_success_url(self, **kwargs):
@ -67,7 +67,7 @@ class BasicFoodUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
model = BasicFood model = BasicFood
form_class = BasicFoodForms form_class = BasicFoodForms
template_name = 'food/basicfood_form.html' template_name = 'food/basicfood_form.html'
extra_context = {"title": _("Add a new aliment")} extra_context = {"title": _("Update an aliment")}
@transaction.atomic @transaction.atomic
def form_valid(self, form): def form_valid(self, form):
@ -86,36 +86,29 @@ class BasicFoodUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
form = context['form']
# TO DO : Add perms here
if 1==0:
form.fields['is_active'].widget = HiddenInput()
if 1==0:
form.fields['was_eaten'].widget = HiddenInput()
form.fields['is_active'].help_text = _("Uncheck if the food doesn't exist anymore")
form.fields['was_eaten'].help_text = _("Check if the food has been entirely eaten")
return context return context
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): class FoodView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
""" """
A view to see a food A view to see a food
""" """
model = Food model = Food
extra_context = {"title": _("Details")} extra_context = {"title": _("Details of:")}
context_object_name = "food" context_object_name = "food"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["can_update"] = PermissionBackend.check_perm(self.request, "food.change_food")
context["can_add_ingredient"] = PermissionBackend.check_perm(self.request, "food.change_transformedfood")
return context
class QRCodeBasicFoodCreateView(ProtectQuerysetMixin, ProtectedCreateView): class QRCodeBasicFoodCreateView(ProtectQuerysetMixin, ProtectedCreateView):
##################################################################### #####################################################################
# TO DO # TO DO
# - this feature is very pratical for meat or fish, nevertheless we can implement this later
# - fix picture save # - fix picture save
# - implement solution crop and convert image (reuse or recode ImageForm from members apps) # - implement solution crop and convert image (reuse or recode ImageForm from members apps)
##################################################################### #####################################################################
@ -157,9 +150,18 @@ class QRCodeBasicFoodCreateView(ProtectQuerysetMixin, ProtectedCreateView):
return reverse('food:qrcode_view', kwargs={"slug": self.kwargs['slug']}) return reverse('food:qrcode_view', kwargs={"slug": self.kwargs['slug']})
def get_sample_object(self): def get_sample_object(self):
# We choose a club which may work or BDE else
owner_id = 1
for membership in self.request.user.memberships.all():
club_id = membership.club.id
food = BasicFood(name="", expiry_date=timezone.now(), owner_id=club_id)
if PermissionBackend.check_perm(self.request, "food.add_basicfood", food):
owner_id = club_id
return BasicFood( return BasicFood(
name="", name="",
expiry_date=timezone.now(), expiry_date=timezone.now(),
owner_id=owner_id,
) )
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -210,7 +212,6 @@ class QRCodeCreateView(ProtectQuerysetMixin, ProtectedCreateView):
qrcode.save() qrcode.save()
qrcode.refresh_from_db() qrcode.refresh_from_db()
qrcode.food_container.is_ready = True
qrcode.food_container.save() qrcode.food_container.save()
return super().form_valid(form) return super().form_valid(form)
@ -222,6 +223,7 @@ class QRCodeCreateView(ProtectQuerysetMixin, ProtectedCreateView):
def get_sample_object(self): def get_sample_object(self):
return QRCode( return QRCode(
qr_code_number=self.kwargs["slug"], qr_code_number=self.kwargs["slug"],
food_container_id=1
) )
@ -243,11 +245,19 @@ class QRCodeView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
# TO DO : Add perms here
context["can_update_basic"]=True
context["can_update_transformed"]=True
context["can_add_ingredient"] = True
qr_code_number = self.kwargs['slug']
qrcode = self.model.objects.get(qr_code_number=qr_code_number)
model = qrcode.food_container.polymorphic_ctype.model
if model == "basicfood":
context["can_update_basic"] = PermissionBackend.check_perm(self.request, "food.change_basicfood")
context["can_view_detail"] = PermissionBackend.check_perm(self.request, "food.view_basicfood")
if model == "transformedfood":
context["can_update_transformed"] = PermissionBackend.check_perm(self.request, "food.change_transformedfood")
context["can_view_detail"] = PermissionBackend.check_perm(self.request, "food.view_transformedfood")
context["can_add_ingredient"] = PermissionBackend.check_perm(self.request, "food.change_transformedfood")
return context return context
@ -255,9 +265,8 @@ class TransformedFoodCreateView(ProtectQuerysetMixin, ProtectedCreateView):
""" """
A view to add a tranformed food A view to add a tranformed food
""" """
# TO DO : fix the "NotImplementedError" (╯°□°)╯︵ ┻━┻ ...
model = TransformedFood model = TransformedFood
template_name = 'food/transformed_food_form.html' template_name = 'food/transformedfood_form.html'
form_class = TransformedFoodForms form_class = TransformedFoodForms
extra_context = {"title": _("Add a new meal")} extra_context = {"title": _("Add a new meal")}
@ -285,6 +294,26 @@ class TransformedFoodCreateView(ProtectQuerysetMixin, ProtectedCreateView):
self.object.refresh_from_db() self.object.refresh_from_db()
return reverse('food:food_view', kwargs={"pk": self.object.pk}) return reverse('food:food_view', kwargs={"pk": self.object.pk})
def get_sample_object(self):
# We choose a club which may work or BDE else
owner_id = 1
for membership in self.request.user.memberships.all():
club_id = membership.club.id
food = TransformedFood(name="",
creation_date=timezone.now(),
expiry_date=timezone.now(),
owner_id=club_id)
if PermissionBackend.check_perm(self.request, "food.add_transformedfood", food):
owner_id = club_id
break
return TransformedFood(
name="",
owner_id=owner_id,
creation_date=timezone.now(),
expiry_date=timezone.now(),
)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
@ -293,10 +322,6 @@ class TransformedFoodCreateView(ProtectQuerysetMixin, ProtectedCreateView):
form.fields['is_active'].widget = HiddenInput() form.fields['is_active'].widget = HiddenInput()
form.fields['is_ready'].widget = HiddenInput() form.fields['is_ready'].widget = HiddenInput()
form.fields['was_eaten'].widget = HiddenInput() form.fields['was_eaten'].widget = HiddenInput()
# Field shelf life is only display for authorized user
# TO DO : Add permission here
if not True:
form.fields['shelf_life'].widget = HiddenInput() form.fields['shelf_life'].widget = HiddenInput()
return context return context
@ -307,9 +332,9 @@ class TransformedFoodUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, Update
A view to update transformed product A view to update transformed product
""" """
model = TransformedFood model = TransformedFood
template_name = 'food/transformed_food_form.html' template_name = 'food/transformedfood_form.html'
form_class = TransformedFoodForms form_class = TransformedFoodForms
extra_context = {'title' : _('Update meal')} extra_context = {'title': _('Update a meal')}
@transaction.atomic @transaction.atomic
def form_valid(self, form): def form_valid(self, form):
@ -328,16 +353,9 @@ class TransformedFoodUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, Update
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
form = context['form']
fields = ['is_active','is_ready','was_eaten','shelf_life']
# TO DO : Add permissions here
permissions = [True]*len(fields)
for i in range(len(fields)):
if not permissions[i] : form[fields[i]].widget = HiddenInput()
return context return context
class TransformedListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView): class TransformedListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMixin, ListView):
""" """
Displays ready TransformedFood Displays ready TransformedFood
@ -361,11 +379,11 @@ class TransformedListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMi
# first table = all transformed food, second table = free, third = served # first table = all transformed food, second table = free, third = served
return [ return [
self.get_queryset().order_by("-creation_date"), self.get_queryset().order_by("-creation_date"),
TransformedFood.objects.filter(is_ready=True,is_active=True,was_eaten=False,expiry_date__lt=timezone.now()) 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")) .filter(PermissionBackend.filter_queryset(self.request, TransformedFood, "view"))
.distinct() .distinct()
.order_by("-creation_date"), .order_by("-creation_date"),
TransformedFood.objects.filter(is_ready=True,is_active=True,was_eaten=False,expiry_date__gte=timezone.now()) 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")) .filter(PermissionBackend.filter_queryset(self.request, TransformedFood, "view"))
.distinct() .distinct()
.order_by("-creation_date") .order_by("-creation_date")
@ -374,8 +392,18 @@ class TransformedListView(ProtectQuerysetMixin, LoginRequiredMixin, MultiTableMi
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**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 # We choose a club which should work
context["can_create_meal"] = True for membership in self.request.user.memberships.all():
club_id = membership.club.id
food = TransformedFood(
name="",
owner_id=club_id,
creation_date=timezone.now(),
expiry_date=timezone.now(),
)
if PermissionBackend.check_perm(self.request, "food.add_transformedfood", food):
context['can_create_meal'] = True
break
tables = context["tables"] tables = context["tables"]
for name, table in zip(["table", "open", "served"], tables): for name, table in zip(["table", "open", "served"], tables):

View File

@ -3119,7 +3119,7 @@
"food", "food",
"transformedfood" "transformedfood"
], ],
"query": "[]", "query": "{}",
"type": "view", "type": "view",
"mask": 3, "mask": 3,
"field": "", "field": "",
@ -3159,6 +3159,406 @@
"description": "Voir les plats préparés actifs servis" "description": "Voir les plats préparés actifs servis"
} }
}, },
{
"model": "permission.permission",
"pk": 202,
"fields": {
"model": [
"food",
"qrcode"
],
"query": "{}",
"type": "add",
"mask": 3,
"field": "",
"permanent": false,
"description": "Initialiser un QR code de traçabilité"
}
},
{
"model": "permission.permission",
"pk": 203,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{\"owner\": [\"club\"]}",
"type": "add",
"mask": 3,
"field": "",
"permanent": false,
"description": "Créer un nouvel ingrédient pour son club"
}
},
{
"model": "permission.permission",
"pk": 204,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{}",
"type": "add",
"mask": 3,
"field": "",
"permanent": false,
"description": "Créer un nouvel ingrédient"
}
},
{
"model": "permission.permission",
"pk": 205,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir toute la bouffe"
}
},
{
"model": "permission.permission",
"pk": 206,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{\"is_active\": true}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir toute la bouffe active"
}
},
{
"model": "permission.permission",
"pk": 207,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{\"is_active\": true, \"owner\": [\"club\"]}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir la bouffe active de son club"
}
},
{
"model": "permission.permission",
"pk": 208,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{}",
"type": "change",
"mask": 3,
"field": "",
"permanent": false,
"description": "Modifier de la bouffe"
}
},
{
"model": "permission.permission",
"pk": 209,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{\"is_active\": true, \"was_eaten\": false}",
"type": "change",
"mask": 3,
"field": "allergens",
"permanent": false,
"description": "Modifier les allergènes de la bouffe existante"
}
},
{
"model": "permission.permission",
"pk": 210,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{\"is_active\": true, \"was_eaten\": false, \"owner\": [\"club\"]}",
"type": "change",
"mask": 3,
"field": "allergens",
"permanent": false,
"description": "Modifier les allergènes de la bouffe appartenant à son club"
}
},
{
"model": "permission.permission",
"pk": 211,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{}",
"type": "add",
"mask": 3,
"field": "",
"permanent": false,
"description": "Créer un plat"
}
},
{
"model": "permission.permission",
"pk": 212,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{\"owner\": [\"club\"]}",
"type": "add",
"mask": 3,
"field": "",
"permanent": false,
"description": "Créer un plat pour son club"
}
},
{
"model": "permission.permission",
"pk": 213,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{}",
"type": "change",
"mask": 3,
"field": "",
"permanent": false,
"description": "Modifier tout les plats"
}
},
{
"model": "permission.permission",
"pk": 214,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{\"is_active\": true}",
"type": "change",
"mask": 3,
"field": "was_eaten",
"permanent": false,
"description": "Indiquer si un plat a été mangé"
}
},
{
"model": "permission.permission",
"pk": 215,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{\"is_active\": true, \"owner\": [\"club\"]}",
"type": "change",
"mask": 3,
"field": "is_ready",
"permanent": false,
"description": "Indiquer si un plat de son club est prêt"
}
},
{
"model": "permission.permission",
"pk": 216,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{\"is_active\": true}",
"type": "change",
"mask": 3,
"field": "is_active",
"permanent": false,
"description": "Archiver un plat"
}
},
{
"model": "permission.permission",
"pk": 217,
"fields": {
"model": [
"food",
"basicfood"
],
"query": "{\"is_active\": true}",
"type": "change",
"mask": 3,
"field": "is_active",
"permanent": false,
"description": "Archiver de la bouffe"
}
},
{
"model": "permission.permission",
"pk": 218,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{\"is_active\": true}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir tout les plats actifs"
}
},
{
"model": "permission.permission",
"pk": 219,
"fields": {
"model": [
"food",
"qrcode"
],
"query": "{}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir tous les QR codes"
}
},
{
"model": "permission.permission",
"pk": 220,
"fields": {
"model": [
"food",
"qrcode"
],
"query": "{\"food_container__is_active\": true}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir tous les QR codes actifs"
}
},
{
"model": "permission.permission",
"pk": 221,
"fields": {
"model": [
"food",
"qrcode"
],
"query": "{\"food_container__owner\": [\"club\"], \"food_container__is_active\": true}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir tous les QR codes actifs de son club"
}
},
{
"model": "permission.permission",
"pk" : 222,
"fields": {
"model": [
"food",
"transformedfood"
],
"query": "{\"owner\": [\"club\"], \"is_active\": true}",
"type": "change",
"mask": 3,
"field": "ingredients",
"permanent": false,
"description": "Changer les ingrédients d'un plat actif de son club"
}
},
{
"model": "permission.permission",
"pk": 223,
"fields": {
"model": [
"food",
"food"
],
"query": "{}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir bouffe"
}
},
{
"model": "permission.permission",
"pk": 224,
"fields": {
"model": [
"food",
"food"
],
"query": "{\"is_active\": true}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir bouffe active"
}
},
{
"model": "permission.permission",
"pk": 225,
"fields": {
"model": [
"food",
"food"
],
"query": "{\"is_active\": true, \"owner\": [\"club\"]}",
"type": "view",
"mask": 3,
"field": "",
"permanent": false,
"description": "Voir bouffe active de son club"
}
},
{
"model": "permission.permission",
"pk": 226,
"fields": {
"model": [
"food",
"food"
],
"query": "{}",
"type": "change",
"mask": 3,
"field": "",
"permanent": false,
"description": "Modifier bouffe"
}
},
{ {
"model": "permission.role", "model": "permission.role",
"pk": 1, "pk": 1,
@ -3266,7 +3666,16 @@
50, 50,
141, 141,
169, 169,
200 200,
202,
203,
207,
210,
212,
215,
221,
222,
225
] ]
} }
}, },
@ -3441,7 +3850,20 @@
167, 167,
168, 168,
182, 182,
200 200,
202,
203,
206,
209,
212,
214,
215,
216,
217,
218,
220,
222,
224
] ]
} }
}, },
@ -3671,7 +4093,17 @@
"for_club": 2, "for_club": 2,
"name": "Respo Bouffe", "name": "Respo Bouffe",
"permissions": [ "permissions": [
199 137,
199,
202,
204,
205,
208,
211,
213,
219,
223,
226
] ]
} }
}, },