mirror of https://gitlab.crans.org/bde/nk20
Add order interface
Signed-off-by: Emmy D'ANELLO <ynerant@crans.org>
This commit is contained in:
parent
5174c84b33
commit
45334e4e02
|
@ -0,0 +1,17 @@
|
|||
{% extends "base.html" %}
|
||||
{% comment %}
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
{% endcomment %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card bg-light mb-3">
|
||||
<h3 class="card-header text-center">
|
||||
{{ title }}
|
||||
</h3>
|
||||
<div class="card-body">
|
||||
{% crispy form %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -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'],))
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-08-18 14:49+0200\n"
|
||||
"POT-Creation-Date: 2022-08-18 17:20+0200\n"
|
||||
"PO-Revision-Date: 2022-04-11 22:05+0200\n"
|
||||
"Last-Translator: elkmaennchen <elkmaennchen@crans.org>\n"
|
||||
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
|
||||
|
@ -1476,7 +1476,7 @@ msgstr "modèles de transaction"
|
|||
msgid "used alias"
|
||||
msgstr "alias utilisé"
|
||||
|
||||
#: apps/note/models/transactions.py:136
|
||||
#: apps/note/models/transactions.py:136 apps/sheets/views.py:276
|
||||
msgid "quantity"
|
||||
msgstr "quantité"
|
||||
|
||||
|
@ -2188,7 +2188,7 @@ msgid "the note sheet will be private until this field is checked."
|
|||
msgstr "la feuille de note restera privée tant que ce champ n'est pas coché."
|
||||
|
||||
#: apps/sheets/models.py:41 apps/sheets/models.py:54 apps/sheets/models.py:116
|
||||
#: apps/sheets/models.py:151 apps/sheets/models.py:268
|
||||
#: apps/sheets/models.py:151 apps/sheets/models.py:273
|
||||
msgid "note sheet"
|
||||
msgstr "feuille de note"
|
||||
|
||||
|
@ -2231,7 +2231,8 @@ msgstr "options de nourriture"
|
|||
msgid "content"
|
||||
msgstr "contenu"
|
||||
|
||||
#: apps/sheets/models.py:143 apps/sheets/models.py:184
|
||||
#: apps/sheets/models.py:140 apps/sheets/models.py:143
|
||||
#: apps/sheets/models.py:180
|
||||
msgid "meal"
|
||||
msgstr "menu"
|
||||
|
||||
|
@ -2243,19 +2244,20 @@ msgstr "menus"
|
|||
msgid "date"
|
||||
msgstr "date"
|
||||
|
||||
#: apps/sheets/models.py:166
|
||||
msgid "gift"
|
||||
msgstr "don"
|
||||
|
||||
#: apps/sheets/models.py:170 apps/sheets/models.py:178
|
||||
#: apps/sheets/models.py:166 apps/sheets/models.py:174
|
||||
#: apps/sheets/models.py:196
|
||||
msgid "order"
|
||||
msgstr "commande"
|
||||
|
||||
#: apps/sheets/models.py:171
|
||||
#: apps/sheets/models.py:167
|
||||
msgid "orders"
|
||||
msgstr "commandes"
|
||||
|
||||
#: apps/sheets/models.py:184 apps/sheets/models.py:233 apps/sheets/views.py:235
|
||||
#: apps/sheets/views.py:280
|
||||
msgid "gift"
|
||||
msgstr "don"
|
||||
|
||||
#: apps/sheets/models.py:188 apps/sheets/models.py:204
|
||||
msgid "ordered meal"
|
||||
msgstr "menu commandé"
|
||||
|
@ -2268,56 +2270,56 @@ msgstr "menus commandés"
|
|||
msgid "options"
|
||||
msgstr "options"
|
||||
|
||||
#: apps/sheets/models.py:222
|
||||
#: apps/sheets/models.py:222 apps/sheets/views.py:242 apps/sheets/views.py:287
|
||||
msgid "remark"
|
||||
msgstr "remarques"
|
||||
|
||||
#: apps/sheets/models.py:229
|
||||
#: apps/sheets/models.py:229 apps/sheets/views.py:248 apps/sheets/views.py:293
|
||||
msgid "priority request"
|
||||
msgstr "demande de priorité"
|
||||
|
||||
#: apps/sheets/models.py:233
|
||||
#: apps/sheets/models.py:237
|
||||
msgid "number"
|
||||
msgstr "numéro"
|
||||
|
||||
#: apps/sheets/models.py:234
|
||||
#: apps/sheets/models.py:238
|
||||
msgid "How many times the user ordered this."
|
||||
msgstr "Combien de fois cet⋅te utilisateur⋅rice a commandé ceci."
|
||||
|
||||
#: apps/sheets/models.py:240
|
||||
#: apps/sheets/models.py:244
|
||||
msgid "queued"
|
||||
msgstr "en attente"
|
||||
|
||||
#: apps/sheets/models.py:241
|
||||
#: apps/sheets/models.py:245
|
||||
msgid "ready"
|
||||
msgstr "prêt"
|
||||
|
||||
#: apps/sheets/models.py:242
|
||||
#: apps/sheets/models.py:246
|
||||
msgid "served"
|
||||
msgstr "servi"
|
||||
|
||||
#: apps/sheets/models.py:243
|
||||
#: apps/sheets/models.py:247
|
||||
msgid "canceled"
|
||||
msgstr "annulé"
|
||||
|
||||
#: apps/sheets/models.py:245
|
||||
#: apps/sheets/models.py:250
|
||||
msgid "status"
|
||||
msgstr "statut"
|
||||
|
||||
#: apps/sheets/models.py:251
|
||||
#: apps/sheets/models.py:256
|
||||
msgid "served date"
|
||||
msgstr "date de service"
|
||||
|
||||
#: apps/sheets/models.py:255 apps/sheets/models.py:256
|
||||
#: apps/sheets/models.py:263
|
||||
#: apps/sheets/models.py:260 apps/sheets/models.py:261
|
||||
#: apps/sheets/models.py:268
|
||||
msgid "ordered food"
|
||||
msgstr "nourriture commandée"
|
||||
|
||||
#: apps/sheets/models.py:281
|
||||
#: apps/sheets/models.py:288
|
||||
msgid "sheet order transaction"
|
||||
msgstr "transaction de commande sur feuille de note"
|
||||
|
||||
#: apps/sheets/models.py:282
|
||||
#: apps/sheets/models.py:289
|
||||
msgid "sheet order transactions"
|
||||
msgstr "transactions de commande sur feuille de note"
|
||||
|
||||
|
@ -2347,7 +2349,8 @@ msgstr "Ajouter un plat"
|
|||
msgid "Add new meal"
|
||||
msgstr "Ajouter un menu"
|
||||
|
||||
#: apps/sheets/templates/sheets/sheet_detail.html:79
|
||||
#: apps/sheets/templates/sheets/sheet_detail.html:79 apps/sheets/views.py:206
|
||||
#: apps/sheets/views.py:317
|
||||
msgid "Order now"
|
||||
msgstr "Commander maintenant"
|
||||
|
||||
|
@ -2359,34 +2362,70 @@ msgstr "Créer une feuille de note"
|
|||
msgid "Note sheet listing"
|
||||
msgstr "Liste des feuilles de notes"
|
||||
|
||||
#: apps/sheets/views.py:23
|
||||
#: apps/sheets/views.py:33
|
||||
msgid "Search note sheet"
|
||||
msgstr "Chercher une feuille de note"
|
||||
|
||||
#: apps/sheets/views.py:38
|
||||
#: apps/sheets/views.py:48
|
||||
msgid "Create note sheet"
|
||||
msgstr "Créer une feuille de note"
|
||||
|
||||
#: apps/sheets/views.py:51
|
||||
#: apps/sheets/views.py:61
|
||||
msgid "Update note sheet"
|
||||
msgstr "Modifier une feuille de note"
|
||||
|
||||
#: apps/sheets/views.py:74
|
||||
#: apps/sheets/views.py:84
|
||||
msgid "Create new food"
|
||||
msgstr "Créer un plat"
|
||||
|
||||
#: apps/sheets/views.py:120
|
||||
#: apps/sheets/views.py:130
|
||||
msgid "Update food"
|
||||
msgstr "Modifier un plat"
|
||||
|
||||
#: apps/sheets/views.py:157
|
||||
#: apps/sheets/views.py:167
|
||||
msgid "Create new meal"
|
||||
msgstr "Créer un menu"
|
||||
|
||||
#: apps/sheets/views.py:182
|
||||
#: apps/sheets/views.py:192
|
||||
msgid "Update meal"
|
||||
msgstr "Modifier un menu"
|
||||
|
||||
#: apps/sheets/views.py:217
|
||||
#, fuzzy
|
||||
#| msgid "order"
|
||||
msgid "Orderer"
|
||||
msgstr "commande"
|
||||
|
||||
#: apps/sheets/views.py:223
|
||||
#, fuzzy
|
||||
#| msgid "orders"
|
||||
msgid "Who orders"
|
||||
msgstr "commandes"
|
||||
|
||||
#: apps/sheets/views.py:231 apps/treasury/models.py:140
|
||||
msgid "Quantity"
|
||||
msgstr "Quantité"
|
||||
|
||||
#: apps/sheets/views.py:243 apps/sheets/views.py:288
|
||||
msgid "Allergies,…"
|
||||
msgstr "Allergies,…"
|
||||
|
||||
#: apps/sheets/views.py:249 apps/sheets/views.py:294
|
||||
msgid "Lesson at 13h30,…"
|
||||
msgstr "Cours à 13h30,…"
|
||||
|
||||
#: apps/sheets/views.py:260
|
||||
msgid "Options for "
|
||||
msgstr "Options pour "
|
||||
|
||||
#: apps/sheets/views.py:304
|
||||
msgid "Options"
|
||||
msgstr "Options"
|
||||
|
||||
#: apps/sheets/views.py:401
|
||||
msgid "You didn't select anything."
|
||||
msgstr "Vous n'avez rien sélectionné."
|
||||
|
||||
#: apps/treasury/apps.py:12 note_kfet/templates/base.html:96
|
||||
msgid "Treasury"
|
||||
msgstr "Trésorerie"
|
||||
|
@ -2473,10 +2512,6 @@ msgstr "Facture n°{id}"
|
|||
msgid "Designation"
|
||||
msgstr "Désignation"
|
||||
|
||||
#: apps/treasury/models.py:140
|
||||
msgid "Quantity"
|
||||
msgstr "Quantité"
|
||||
|
||||
#: apps/treasury/models.py:145
|
||||
msgid "Unit price"
|
||||
msgstr "Prix unitaire"
|
||||
|
|
Loading…
Reference in New Issue