diff --git a/apps/sheets/forms.py b/apps/sheets/forms.py
index 32fe0b72..00c313ec 100644
--- a/apps/sheets/forms.py
+++ b/apps/sheets/forms.py
@@ -1,12 +1,12 @@
# Copyright (C) 2018-2022 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
-
+from crispy_forms.helper import FormHelper
from django import forms
from member.models import Club
from note_kfet.inputs import AmountInput, Autocomplete, DateTimePickerInput
-from .models import Food, Meal, Sheet
+from .models import Food, FoodOption, Meal, Sheet
class SheetForm(forms.ModelForm):
@@ -31,6 +31,32 @@ class FoodForm(forms.ModelForm):
}
+class FoodOptionForm(forms.ModelForm):
+ class Meta:
+ model = FoodOption
+ fields = '__all__'
+ widgets = {
+ 'extra_cost': AmountInput(),
+ }
+
+
+FoodOptionsFormSet = forms.inlineformset_factory(
+ Food,
+ FoodOption,
+ form=FoodOptionForm,
+ extra=0,
+)
+
+
+class FoodOptionFormSetHelper(FormHelper):
+ def __init__(self, form=None):
+ super().__init__(form)
+ self.form_tag = False
+ self.form_method = 'POST'
+ self.form_class = 'form-inline'
+ self.template = 'bootstrap4/table_inline_formset.html'
+
+
class MealForm(forms.ModelForm):
class Meta:
model = Meal
diff --git a/apps/sheets/templates/sheets/food_form.html b/apps/sheets/templates/sheets/food_form.html
index c62fec40..0b13f206 100644
--- a/apps/sheets/templates/sheets/food_form.html
+++ b/apps/sheets/templates/sheets/food_form.html
@@ -14,8 +14,73 @@ SPDX-License-Identifier: GPL-3.0-or-later
-{% endblock %}
\ No newline at end of file
+
+{# Hidden div that store an empty product form, to be copied into new forms #}
+
+{% endblock %}
+
+{% block extrajavascript %}
+
+{% endblock %}
diff --git a/apps/sheets/templates/sheets/sheet_detail.html b/apps/sheets/templates/sheets/sheet_detail.html
index a52a69ff..3163d8e9 100644
--- a/apps/sheets/templates/sheets/sheet_detail.html
+++ b/apps/sheets/templates/sheets/sheet_detail.html
@@ -28,7 +28,7 @@
{% trans "menu"|capfirst %} :
{% for meal in sheet.meal_set.all %}
- -
+
-
{{ meal }} ({{ meal.price|pretty_money }})
{% if can_change_sheet %}
@@ -40,7 +40,7 @@
{% endfor %}
{% for food in sheet.food_set.all %}
- -
+
-
{{ food }} ({{ food.price|pretty_money }})
{% if can_change_sheet %}
@@ -48,11 +48,11 @@
{% trans "Edit" %}
{% endif %}
- {% if food.option_set.all %}
+ {% if food.foodoption_set.all %}
- {% for option in food.available_options %}
- -
- {{ option }}{% if option.extra_price %} ({{ option.extra_price|pretty_money }}){% endif %}
+ {% for option in food.foodoption_set.all %}
+
-
+ {{ option }}{% if option.extra_cost %} ({{ option.extra_cost|pretty_money }}){% endif %}
{% endfor %}
diff --git a/apps/sheets/views.py b/apps/sheets/views.py
index 1a241369..ddf66d98 100644
--- a/apps/sheets/views.py
+++ b/apps/sheets/views.py
@@ -1,6 +1,6 @@
# Copyright (C) 2018-2022 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
-
+from crispy_forms.helper import FormHelper
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.utils import timezone
@@ -11,7 +11,7 @@ from django_tables2 import SingleTableView
from permission.backends import PermissionBackend
from permission.views import ProtectQuerysetMixin, ProtectedCreateView
-from .forms import FoodForm, MealForm, SheetForm
+from .forms import FoodForm, MealForm, SheetForm, FoodOptionsFormSet, FoodOptionFormSetHelper
from .models import Sheet, Food, Meal
from .tables import SheetTable
@@ -80,8 +80,34 @@ class FoodCreateView(ProtectQuerysetMixin, ProtectedCreateView):
price=500,
)
+ 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 products
+ form_set = FoodOptionsFormSet(instance=form.instance)
+ context['formset'] = form_set
+ context['helper'] = FoodOptionFormSetHelper()
+
+ return context
+
def form_valid(self, form):
form.instance.sheet_id = self.kwargs['pk']
+
+ # For each product, we save it
+ formset = FoodOptionsFormSet(self.request.POST, instance=form.instance)
+ if formset.is_valid():
+ for f in formset:
+ # We don't save the product if the designation is not entered, ie. if the line is empty
+ if f.is_valid() and f.instance.name:
+ f.save()
+ f.instance.save()
+ else:
+ f.instance = None
+
return super().form_valid(form)
def get_success_url(self):
@@ -93,8 +119,36 @@ class FoodUpdateView(ProtectQuerysetMixin, UpdateView):
form_class = FoodForm
extra_context = {"title": _("Update food")}
+ 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 products
+ form_set = FoodOptionsFormSet(instance=form.instance)
+ context['formset'] = form_set
+ context['helper'] = FoodOptionFormSetHelper()
+
+ return context
+
+ def form_valid(self, form):
+ # For each product, we save it
+ formset = FoodOptionsFormSet(self.request.POST, instance=form.instance)
+ if formset.is_valid():
+ for f in formset:
+ # We don't save the product if the designation is not entered, ie. if the line is empty
+ if f.is_valid() and f.instance.name:
+ f.save()
+ f.instance.save()
+ else:
+ f.instance = None
+
+ return super().form_valid(form)
+
def get_success_url(self):
- return reverse_lazy('sheets:sheet_detail', args=(self.kwargs['pk'],))
+ return reverse_lazy('sheets:sheet_detail', args=(self.object.sheet_id,))
class MealCreateView(ProtectQuerysetMixin, ProtectedCreateView):
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index afc19b5b..216346b4 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-08-18 14:24+0200\n"
+"POT-Creation-Date: 2022-08-18 14:49+0200\n"
"PO-Revision-Date: 2022-04-11 22:05+0200\n"
"Last-Translator: elkmaennchen \n"
"Language-Team: French \n"
@@ -337,7 +337,7 @@ msgstr "Entrée effectuée !"
#: apps/member/templates/member/add_members.html:46
#: apps/member/templates/member/club_form.html:16
#: apps/note/templates/note/transactiontemplate_form.html:18
-#: apps/sheets/templates/sheets/food_form.html:17
+#: apps/sheets/templates/sheets/food_form.html:51
#: apps/sheets/templates/sheets/meal_form.html:17
#: apps/sheets/templates/sheets/sheet_form.html:17 apps/treasury/forms.py:89
#: apps/treasury/forms.py:143
@@ -2321,10 +2321,20 @@ msgstr "transaction de commande sur feuille de note"
msgid "sheet order transactions"
msgstr "transactions de commande sur feuille de note"
+#: apps/sheets/templates/sheets/food_form.html:48
+msgid "Add option"
+msgstr "Ajouter une option"
+
#: apps/sheets/templates/sheets/sheet_detail.html:28
msgid "menu"
msgstr "menu"
+#: apps/sheets/templates/sheets/sheet_detail.html:31
+#: apps/sheets/templates/sheets/sheet_detail.html:43
+#: apps/sheets/templates/sheets/sheet_detail.html:54
+msgid "This product is unavailable."
+msgstr "Ce produit est indisponible."
+
#: apps/sheets/templates/sheets/sheet_detail.html:63
msgid "The menu is empty for now."
msgstr "Le menu est vide pour le moment."
@@ -2365,15 +2375,15 @@ msgstr "Modifier une feuille de note"
msgid "Create new food"
msgstr "Créer un plat"
-#: apps/sheets/views.py:94
+#: apps/sheets/views.py:120
msgid "Update food"
msgstr "Modifier un plat"
-#: apps/sheets/views.py:103
+#: apps/sheets/views.py:157
msgid "Create new meal"
msgstr "Créer un menu"
-#: apps/sheets/views.py:128
+#: apps/sheets/views.py:182
msgid "Update meal"
msgstr "Modifier un menu"