mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 09:12:11 +01:00 
			
		
		
		
	
							
								
								
									
										34
									
								
								apps/sheets/migrations/0002_auto_20220818_1713.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								apps/sheets/migrations/0002_auto_20220818_1713.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
# Generated by Django 2.2.27 on 2022-08-18 15:13
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('sheets', '0001_initial'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(
 | 
			
		||||
            model_name='order',
 | 
			
		||||
            name='gift',
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='orderedfood',
 | 
			
		||||
            name='gift',
 | 
			
		||||
            field=models.IntegerField(default=0, verbose_name='gift'),
 | 
			
		||||
            preserve_default=False,
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='orderedmeal',
 | 
			
		||||
            name='gift',
 | 
			
		||||
            field=models.IntegerField(default=0, verbose_name='gift'),
 | 
			
		||||
            preserve_default=False,
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name='orderedfood',
 | 
			
		||||
            name='status',
 | 
			
		||||
            field=models.CharField(choices=[('QUEUED', 'queued'), ('READY', 'ready'), ('SERVED', 'served'), ('CANCELED', 'canceled')], default='QUEUED', max_length=8, verbose_name='status'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -137,7 +137,7 @@ class Meal(models.Model):
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
        return _("meal").capitalize() + " " + self.name
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = _("meal")
 | 
			
		||||
@@ -162,10 +162,6 @@ class Order(models.Model):
 | 
			
		||||
        auto_now_add=True,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    gift = models.IntegerField(
 | 
			
		||||
        verbose_name=_("gift"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = _("order")
 | 
			
		||||
        verbose_name_plural = _("orders")
 | 
			
		||||
@@ -184,6 +180,10 @@ class OrderedMeal(models.Model):
 | 
			
		||||
        verbose_name=_("meal"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    gift = models.IntegerField(
 | 
			
		||||
        verbose_name=_("gift"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = _("ordered meal")
 | 
			
		||||
        verbose_name_plural = _("ordered meals")
 | 
			
		||||
@@ -229,6 +229,10 @@ class OrderedFood(models.Model):
 | 
			
		||||
        verbose_name=_("priority request"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    gift = models.IntegerField(
 | 
			
		||||
        verbose_name=_("gift"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    number = models.IntegerField(
 | 
			
		||||
        verbose_name=_("number"),
 | 
			
		||||
        help_text=_("How many times the user ordered this."),
 | 
			
		||||
@@ -242,6 +246,7 @@ class OrderedFood(models.Model):
 | 
			
		||||
            ('SERVED', _("served")),
 | 
			
		||||
            ('CANCELED', _("canceled")),
 | 
			
		||||
        ],
 | 
			
		||||
        default='QUEUED',
 | 
			
		||||
        verbose_name=_("status"),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@@ -268,14 +273,16 @@ class SheetOrderTransaction(Transaction):
 | 
			
		||||
        return _("note sheet")
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def price(self):
 | 
			
		||||
    def get_price(self):
 | 
			
		||||
        if self.ordered_food.meal:
 | 
			
		||||
            return sum(ordered_food.price + sum(opt.extra_cost for opt in ordered_food.options.all())
 | 
			
		||||
                       for ordered_food in self.ordered_food.meal.orderedfood_set.exclude(status='CANCELED').all())
 | 
			
		||||
            return self.ordered_food.meal.meal.price + self.ordered_food.meal.gift + sum(
 | 
			
		||||
                sum(opt.extra_cost for opt in ordered_food.options.all())
 | 
			
		||||
                for ordered_food in self.ordered_food.meal.orderedfood_set.exclude(status='CANCELED').all())
 | 
			
		||||
        elif self.ordered_food.status == 'CANCELED':
 | 
			
		||||
            return 0
 | 
			
		||||
        else:
 | 
			
		||||
            return self.ordered_food.food.price + sum(opt.extra_cost for opt in self.ordered_food.options.all())
 | 
			
		||||
            return self.ordered_food.food.price + self.ordered_food.gift \
 | 
			
		||||
                   + sum(opt.extra_cost for opt in self.ordered_food.options.all())
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = _("sheet order transaction")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
{% extends "wei/base.html" %}
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
{% comment %}
 | 
			
		||||
SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
{% load crispy_forms_tags %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block profile_content %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="card bg-light mb-3">
 | 
			
		||||
    <h3 class="card-header text-center">
 | 
			
		||||
        {{ title }}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
{% extends "wei/base.html" %}
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
{% comment %}
 | 
			
		||||
SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
{% load crispy_forms_tags %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block profile_content %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="card bg-light mb-3">
 | 
			
		||||
    <h3 class="card-header text-center">
 | 
			
		||||
        {{ title }}
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<div class="card-footer text-center">
 | 
			
		||||
    <a class="btn btn-success">
 | 
			
		||||
    <a href="{% url 'sheets:sheet_order' pk=sheet.pk %}" class="btn btn-success">
 | 
			
		||||
        {% trans "Order now" %}
 | 
			
		||||
    </a>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
{% extends "wei/base.html" %}
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
{% comment %}
 | 
			
		||||
SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
{% load crispy_forms_tags %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block profile_content %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="card bg-light mb-3">
 | 
			
		||||
    <h3 class="card-header text-center">
 | 
			
		||||
        {{ title }}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
 | 
			
		||||
from django.urls import path
 | 
			
		||||
 | 
			
		||||
from sheets.views import FoodCreateView, FoodUpdateView, MealCreateView, MealUpdateView, \
 | 
			
		||||
from sheets.views import FoodCreateView, FoodUpdateView, MealCreateView, MealUpdateView, OrderView, \
 | 
			
		||||
    SheetCreateView, SheetDetailView, SheetListView, SheetUpdateView
 | 
			
		||||
 | 
			
		||||
app_name = 'sheets'
 | 
			
		||||
@@ -17,4 +17,5 @@ urlpatterns = [
 | 
			
		||||
    path('food/<int:pk>/update/', FoodUpdateView.as_view(), name="food_update"),
 | 
			
		||||
    path('meal/create/<int:pk>/', MealCreateView.as_view(), name="meal_create"),
 | 
			
		||||
    path('meal/<int:pk>/update/', MealUpdateView.as_view(), name="meal_update"),
 | 
			
		||||
    path('order/<int:pk>/', OrderView.as_view(), name="sheet_order"),
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,28 @@
 | 
			
		||||
# Copyright (C) 2018-2022 by BDE ENS Paris-Saclay
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
 | 
			
		||||
from crispy_forms.bootstrap import Accordion, AccordionGroup, FormActions
 | 
			
		||||
from crispy_forms.helper import FormHelper
 | 
			
		||||
from crispy_forms.layout import Fieldset, Submit, Row, Field
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.contrib.auth.mixins import LoginRequiredMixin
 | 
			
		||||
from django.db import transaction
 | 
			
		||||
from django.forms import Form
 | 
			
		||||
from django.urls import reverse_lazy
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from django.views.generic import DetailView, UpdateView
 | 
			
		||||
from django.views.generic import DetailView, UpdateView, FormView
 | 
			
		||||
from django_tables2 import SingleTableView
 | 
			
		||||
 | 
			
		||||
from note.models import Alias, Note
 | 
			
		||||
from note.templatetags.pretty_money import pretty_money
 | 
			
		||||
from note_kfet.inputs import AmountInput, Autocomplete
 | 
			
		||||
from permission.backends import PermissionBackend
 | 
			
		||||
from permission.views import ProtectQuerysetMixin, ProtectedCreateView
 | 
			
		||||
 | 
			
		||||
from .forms import FoodForm, MealForm, SheetForm, FoodOptionsFormSet, FoodOptionFormSetHelper
 | 
			
		||||
from .models import Sheet, Food, Meal
 | 
			
		||||
from .models import Sheet, Food, Meal, Order, OrderedMeal, OrderedFood, SheetOrderTransaction
 | 
			
		||||
from .tables import SheetTable
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -45,13 +55,13 @@ class SheetCreateView(ProtectQuerysetMixin, ProtectedCreateView):
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SheetUpdateView(ProtectQuerysetMixin, UpdateView):
 | 
			
		||||
class SheetUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
 | 
			
		||||
    model = Sheet
 | 
			
		||||
    form_class = SheetForm
 | 
			
		||||
    extra_context = {"title": _("Update note sheet")}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SheetDetailView(ProtectQuerysetMixin, DetailView):
 | 
			
		||||
class SheetDetailView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
 | 
			
		||||
    model = Sheet
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
@@ -114,7 +124,7 @@ class FoodCreateView(ProtectQuerysetMixin, ProtectedCreateView):
 | 
			
		||||
        return reverse_lazy('sheets:sheet_detail', args=(self.kwargs['pk'],))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FoodUpdateView(ProtectQuerysetMixin, UpdateView):
 | 
			
		||||
class FoodUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
 | 
			
		||||
    model = Food
 | 
			
		||||
    form_class = FoodForm
 | 
			
		||||
    extra_context = {"title": _("Update food")}
 | 
			
		||||
@@ -176,7 +186,7 @@ class MealCreateView(ProtectQuerysetMixin, ProtectedCreateView):
 | 
			
		||||
        return reverse_lazy('sheets:sheet_detail', args=(self.object.sheet_id,))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MealUpdateView(ProtectQuerysetMixin, UpdateView):
 | 
			
		||||
class MealUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
 | 
			
		||||
    model = Meal
 | 
			
		||||
    form_class = MealForm
 | 
			
		||||
    extra_context = {"title": _("Update meal")}
 | 
			
		||||
@@ -188,3 +198,211 @@ class MealUpdateView(ProtectQuerysetMixin, UpdateView):
 | 
			
		||||
 | 
			
		||||
    def get_success_url(self):
 | 
			
		||||
        return reverse_lazy('sheets:sheet_detail', args=(self.object.sheet_id,))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OrderView(LoginRequiredMixin, FormView, DetailView):
 | 
			
		||||
    model = Sheet
 | 
			
		||||
    template_name = 'sheets/order.html'
 | 
			
		||||
    extra_context = {'title': _("Order now")}
 | 
			
		||||
 | 
			
		||||
    def get_form(self, form_class=None):
 | 
			
		||||
        form = Form()
 | 
			
		||||
        form.helper = FormHelper()
 | 
			
		||||
        layout_fields = []
 | 
			
		||||
 | 
			
		||||
        self.object = self.get_object()
 | 
			
		||||
 | 
			
		||||
        form.fields['note'] = forms.ModelChoiceField(
 | 
			
		||||
            queryset=Note.objects.filter(PermissionBackend.filter_queryset(self.request, Note, 'note.view_note')),
 | 
			
		||||
            label=_("Orderer"),
 | 
			
		||||
            initial=self.request.user.note,
 | 
			
		||||
            widget=Autocomplete(
 | 
			
		||||
                model=Note,
 | 
			
		||||
                attrs={
 | 
			
		||||
                    "api_url": "/api/note/note/",
 | 
			
		||||
                    'placeholder': _("Who orders")
 | 
			
		||||
                },
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
        layout_fields.append(Field('note', css_class='is-valid'))
 | 
			
		||||
 | 
			
		||||
        for meal in self.object.meal_set.filter(available=True).all():
 | 
			
		||||
            form.fields[f'meal_{meal.id}_quantity'] = forms.IntegerField(
 | 
			
		||||
                label=_("Quantity"),
 | 
			
		||||
                initial=0,
 | 
			
		||||
            )
 | 
			
		||||
            form.fields[f'meal_{meal.id}_gift'] = forms.IntegerField(
 | 
			
		||||
                label=_("gift").capitalize(),
 | 
			
		||||
                initial=0,
 | 
			
		||||
                widget=AmountInput(),
 | 
			
		||||
            )
 | 
			
		||||
            form.fields[f'meal_{meal.id}_remark'] = forms.CharField(
 | 
			
		||||
                max_length=255,
 | 
			
		||||
                required=False,
 | 
			
		||||
                label=_("remark").capitalize(),
 | 
			
		||||
                help_text=_("Allergies,…"),
 | 
			
		||||
            )
 | 
			
		||||
            form.fields[f'meal_{meal.id}_priority'] = forms.CharField(
 | 
			
		||||
                max_length=64,
 | 
			
		||||
                required=False,
 | 
			
		||||
                label=_("priority request").capitalize(),
 | 
			
		||||
                help_text=_("Lesson at 13h30,…"),
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            ag = AccordionGroup(f"{meal} ({pretty_money(meal.price)})",
 | 
			
		||||
                                Row(Field(f'meal_{meal.id}_quantity', wrapper_class='col-sm-9'),
 | 
			
		||||
                                    Field(f'meal_{meal.id}_gift', wrapper_class='col-sm-3')),
 | 
			
		||||
                                Row(Field(f'meal_{meal.id}_remark', wrapper_class='col-sm-9'),
 | 
			
		||||
                                    Field(f'meal_{meal.id}_priority', wrapper_class='col-sm-3')))
 | 
			
		||||
 | 
			
		||||
            for food in meal.content.filter(available=True).all():
 | 
			
		||||
                if food.foodoption_set.count():
 | 
			
		||||
                    options_fieldset = Fieldset(_("Options for ") + str(food))
 | 
			
		||||
                    options_row = Row(css_class='ml-0')
 | 
			
		||||
                    for option in food.foodoption_set.filter(available=True).all():
 | 
			
		||||
                        form.fields[f'meal_{meal.id}_food_{food.id}_option_{option.id}'] = forms.BooleanField(
 | 
			
		||||
                            label=f"{option}{f' ({pretty_money(option.extra_cost)})' if option.extra_cost else ''}",
 | 
			
		||||
                            required=False,
 | 
			
		||||
                        )
 | 
			
		||||
                        options_row.fields.append(
 | 
			
		||||
                            Field(f'meal_{meal.id}_food_{food.id}_option_{option.id}', wrapper_class='col-sm-12'))
 | 
			
		||||
                    options_fieldset.fields.append(options_row)
 | 
			
		||||
                    ag.fields.append(options_fieldset)
 | 
			
		||||
 | 
			
		||||
            layout_fields.append(ag)
 | 
			
		||||
 | 
			
		||||
        for food in self.object.food_set.filter(available=True).all():
 | 
			
		||||
            form.fields[f'food_{food.id}_quantity'] = forms.IntegerField(
 | 
			
		||||
                label=_("quantity").capitalize(),
 | 
			
		||||
                initial=0,
 | 
			
		||||
            )
 | 
			
		||||
            form.fields[f'food_{food.id}_gift'] = forms.IntegerField(
 | 
			
		||||
                label=_("gift").capitalize(),
 | 
			
		||||
                initial=0,
 | 
			
		||||
                widget=AmountInput(),
 | 
			
		||||
            )
 | 
			
		||||
            form.fields[f'food_{food.id}_remark'] = forms.CharField(
 | 
			
		||||
                max_length=255,
 | 
			
		||||
                required=False,
 | 
			
		||||
                label=_("remark").capitalize(),
 | 
			
		||||
                help_text=_("Allergies,…"),
 | 
			
		||||
            )
 | 
			
		||||
            form.fields[f'food_{food.id}_priority'] = forms.CharField(
 | 
			
		||||
                max_length=255,
 | 
			
		||||
                required=False,
 | 
			
		||||
                label=_("priority request").capitalize(),
 | 
			
		||||
                help_text=_("Lesson at 13h30,…"),
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            ag = AccordionGroup(f"{food} ({pretty_money(food.price)})",
 | 
			
		||||
                                Row(Field(f'food_{food.id}_quantity', wrapper_class='col-sm-9'),
 | 
			
		||||
                                    Field(f'food_{food.id}_gift', wrapper_class='col-sm-3')),
 | 
			
		||||
                                Row(Field(f'food_{food.id}_remark', wrapper_class='col-sm-9'),
 | 
			
		||||
                                    Field(f'food_{food.id}_priority', wrapper_class='col-sm-3')))
 | 
			
		||||
 | 
			
		||||
            if food.foodoption_set.count():
 | 
			
		||||
                options_fieldset = Fieldset(_("Options"))
 | 
			
		||||
                options_row = Row(css_class='ml-0')
 | 
			
		||||
                for option in food.foodoption_set.all():
 | 
			
		||||
                    form.fields[f'food_{food.id}_option_{option.id}'] = forms.BooleanField(
 | 
			
		||||
                        label=f"{option}{f' ({pretty_money(option.extra_cost)})' if option.extra_cost else ''}",
 | 
			
		||||
                        required=False,
 | 
			
		||||
                    )
 | 
			
		||||
                    options_row.fields.append(Field(f'food_{food.id}_option_{option.id}', wrapper_class='col-sm-12'))
 | 
			
		||||
                options_fieldset.fields.append(options_row)
 | 
			
		||||
                ag.fields.append(options_fieldset)
 | 
			
		||||
 | 
			
		||||
            layout_fields.append(ag)
 | 
			
		||||
 | 
			
		||||
        layout_fields.append(FormActions(Submit('submit', _("Order now"))))
 | 
			
		||||
 | 
			
		||||
        form.helper.layout = Accordion(*layout_fields)
 | 
			
		||||
 | 
			
		||||
        if self.request.method in ['PUT', 'POST']:
 | 
			
		||||
            form.data = self.request.POST
 | 
			
		||||
            form.files = self.request.FILES
 | 
			
		||||
            form.is_bound = not form.data or not form.files
 | 
			
		||||
 | 
			
		||||
        return form
 | 
			
		||||
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        data = form.cleaned_data
 | 
			
		||||
        sheet = self.get_object()
 | 
			
		||||
 | 
			
		||||
        with transaction.atomic():
 | 
			
		||||
            order = Order.objects.create(sheet_id=self.kwargs['pk'], note=data['note'])
 | 
			
		||||
 | 
			
		||||
            total_quantity = 0
 | 
			
		||||
 | 
			
		||||
            for meal in sheet.meal_set.filter(available=True).all():
 | 
			
		||||
                quantity = data[f'meal_{meal.id}_quantity']
 | 
			
		||||
                if not quantity:
 | 
			
		||||
                    continue
 | 
			
		||||
 | 
			
		||||
                total_quantity += quantity
 | 
			
		||||
                gift = data[f'meal_{meal.id}_gift']
 | 
			
		||||
                remark = data[f'meal_{meal.id}_remark'] or ''
 | 
			
		||||
                priority = data[f'meal_{meal.id}_priority'] or ''
 | 
			
		||||
                ordered_meal = OrderedMeal.objects.create(order=order, meal=meal, gift=gift)
 | 
			
		||||
 | 
			
		||||
                for ignored in range(quantity):
 | 
			
		||||
                    for food in meal.content.filter(available=True).all():
 | 
			
		||||
                        n = OrderedFood.objects.filter(order__sheet_id=self.kwargs['pk'],
 | 
			
		||||
                                                       order__note=order.note,
 | 
			
		||||
                                                       order__date__gte=timezone.now() - timedelta(hours=6),
 | 
			
		||||
                                                       food=food).exclude(status='CANCELED').count()
 | 
			
		||||
                        of = OrderedFood.objects.create(order=order, meal=ordered_meal, food=food,
 | 
			
		||||
                                                        remark=remark, priority=priority, number=n + 1, gift=0)
 | 
			
		||||
 | 
			
		||||
                        for option in food.foodoption_set.filter(available=True).all():
 | 
			
		||||
                            if data[f'meal_{meal.id}_food_{food.id}_option_{option.id}']:
 | 
			
		||||
                                of.options.add(option)
 | 
			
		||||
                        of.save()
 | 
			
		||||
 | 
			
		||||
                first_food = ordered_meal.orderedfood_set.first()
 | 
			
		||||
                tr = SheetOrderTransaction(source_id=order.note_id, destination=first_food.food.club.note,
 | 
			
		||||
                                           source_alias=str(order.note), destination_alias=first_food.food.club.name,
 | 
			
		||||
                                           quantity=quantity, ordered_food=first_food,
 | 
			
		||||
                                           reason=f"{meal.name} - {sheet.name}")
 | 
			
		||||
                tr.amount = tr.get_price / tr.quantity
 | 
			
		||||
                tr.save()
 | 
			
		||||
 | 
			
		||||
            for food in sheet.food_set.filter(available=True).all():
 | 
			
		||||
                quantity = data[f'food_{food.id}_quantity']
 | 
			
		||||
                if not quantity:
 | 
			
		||||
                    continue
 | 
			
		||||
 | 
			
		||||
                total_quantity += quantity
 | 
			
		||||
                gift = data[f'food_{meal.id}_gift']
 | 
			
		||||
                remark = data[f'food_{meal.id}_remark'] or ''
 | 
			
		||||
                priority = data[f'food_{meal.id}_priority'] or ''
 | 
			
		||||
 | 
			
		||||
                for ignored in range(quantity):
 | 
			
		||||
                    n = OrderedFood.objects.filter(order__sheet_id=self.kwargs['pk'],
 | 
			
		||||
                                                   order__note=order.note,
 | 
			
		||||
                                                   order__date__gte=timezone.now() - timedelta(hours=6),
 | 
			
		||||
                                                   food=food).exclude(state='CANCELED').count()
 | 
			
		||||
                    of = OrderedFood.objects.create(order=order, food=food, gift=gift,
 | 
			
		||||
                                                    remark=remark, priority=priority, number=n + 1)
 | 
			
		||||
 | 
			
		||||
                    for option in food.foodoption_set.filter(available=True).all():
 | 
			
		||||
                        if data[f'meal_{meal.id}_food_{food.id}_option_{option.id}']:
 | 
			
		||||
                            of.options.add(option)
 | 
			
		||||
                    of.options.save()
 | 
			
		||||
 | 
			
		||||
                    tr = SheetOrderTransaction(source_id=order.note_id, destination_id=first_food.club.note,
 | 
			
		||||
                                               source_alias=str(order.note), destination_alias=first_food.club.name,
 | 
			
		||||
                                               quantity=quantity, ordered_food=of,
 | 
			
		||||
                                               reason=f"{food.name} - {sheet.name}")
 | 
			
		||||
                    tr.amount = tr.get_price / tr.quantity
 | 
			
		||||
                    tr.save()
 | 
			
		||||
 | 
			
		||||
        if total_quantity == 0:
 | 
			
		||||
            form.add_error(None, _("You didn't select anything."))
 | 
			
		||||
            transaction.rollback()
 | 
			
		||||
            return self.form_invalid(form)
 | 
			
		||||
 | 
			
		||||
        return super().form_valid(form)
 | 
			
		||||
 | 
			
		||||
    def get_success_url(self):
 | 
			
		||||
        return reverse_lazy('sheets:sheet_detail', args=(self.kwargs['pk'],))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user