1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-11-01 16:14:30 +01:00

Alpha version (without tests)

This commit is contained in:
Ehouarn
2025-10-30 23:54:23 +01:00
parent d4cb464169
commit 6bf21b103f
24 changed files with 1229 additions and 14 deletions

View File

@@ -4,10 +4,14 @@
from datetime import timedelta
from django.db import models, transaction
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
from polymorphic.models import PolymorphicModel
from member.models import Club
from activity.models import Activity
from note.models import Transaction
class Allergen(models.Model):
@@ -284,3 +288,199 @@ class QRCode(models.Model):
def __str__(self):
return _('QR-code number') + ' ' + str(self.qr_code_number)
class Dish(models.Model):
"""
A dish is a food proposed during a meal
"""
main = models.ForeignKey(
TransformedFood,
on_delete=models.PROTECT,
related_name='dishes_as_main',
verbose_name=_('main food'),
)
price = models.PositiveIntegerField(
verbose_name=_('price')
)
activity = models.ForeignKey(
Activity,
on_delete=models.CASCADE,
related_name='dishes',
verbose_name=_('activity'),
)
available = models.BooleanField(
default=True,
verbose_name=_('available'),
)
class Meta:
verbose_name = _('Dish')
verbose_name_plural = _('Dishes')
unique_together = ('main', 'activity')
def __str__(self):
return self.main.name + ' (' + str(self.activity) + ')'
def save(self, *args, **kwargs):
"Check the type of activity"
if self.activity.activity_type.name != 'Perm bouffe':
raise ValidationError(_('(You cannot select this type of activity.'))
return super().save(*args, **kwargs)
class Supplement(models.Model):
"""
A supplement is a food added to a dish
"""
dish = models.ForeignKey(
Dish,
on_delete=models.CASCADE,
related_name='supplements',
verbose_name=_('dish'),
)
food = models.ForeignKey(
Food,
on_delete=models.PROTECT,
related_name='supplements',
verbose_name=_('food'),
)
price = models.PositiveIntegerField(
verbose_name=_('price')
)
class Meta:
verbose_name = _('Supplement')
verbose_name_plural = _('Supplements')
def __str__(self):
return _("Supplement {food} for {dish}").format(
food=str(self.food), dish=str(self.dish))
class Order(models.Model):
"""
An order is a dish ordered by a member during an activity
"""
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='food_orders',
verbose_name=_('user'),
)
activity = models.ForeignKey(
Activity,
on_delete=models.CASCADE,
related_name='food_orders',
verbose_name=_('activity'),
)
dish = models.ForeignKey(
Dish,
on_delete=models.CASCADE,
related_name='orders',
verbose_name=_('dish'),
)
supplements = models.ManyToManyField(
Supplement,
related_name='orders',
verbose_name=_('supplements'),
blank=True,
)
request = models.TextField(
blank=True,
verbose_name=_('request'),
help_text=_('A specific request (to remove an ingredient for example)')
)
number = models.PositiveIntegerField(
verbose_name=_('number'),
default=1,
)
ordered_at = models.DateTimeField(
default=timezone.now,
verbose_name=_('order date'),
)
served = models.BooleanField(
default=False,
verbose_name=_('served'),
)
served_at = models.DateTimeField(
null=True,
blank=True,
verbose_name=_('served date'),
)
class Meta:
verbose_name = _('Order')
verbose_name_plural = _('Orders')
unique_together = ('activity', 'number', )
@property
def amount(self):
return self.dish.price + sum(s.price for s in self.supplements.all())
def __str__(self):
return _("Order of {dish} by {user}").format(
dish=str(self.dish),
user=str(self.user))
def save(self, *args, **kwargs):
created = self.pk is None
if created:
last_order = Order.objects.filter(activity=self.activity).last()
if last_order is None:
self.number = 1
else:
self.number = last_order.number + 1
elif self.served:
if FoodTransaction.objects.filter(order=self).exists():
transaction = FoodTransaction.objects.get(order=self)
transaction.valid = True
transaction.save()
else:
transaction = FoodTransaction(
source=self.user.note,
destination=self.activity.organizer.note,
amount=self.amount,
quantity=1,
valid=True,
order=self,
)
transaction.save()
else:
if FoodTransaction.objects.filter(order=self).exists():
transaction = FoodTransaction.objects.get(order=self)
transaction.valid = False
transaction.save()
return super().save(*args, **kwargs)
class FoodTransaction(Transaction):
"""
Special type of :model:`note.Transaction` associated to a :model:`food.Order`.
"""
order = models.ForeignKey(
Order,
on_delete=models.PROTECT,
related_name='transaction',
verbose_name=_('order')
)
class Meta:
verbose_name = _("food transaction")
verbose_name_plural = _("food transactions")