diff --git a/apps/establishment/filters.py b/apps/establishment/filters.py index 37d15dfc..b52c909f 100644 --- a/apps/establishment/filters.py +++ b/apps/establishment/filters.py @@ -126,3 +126,27 @@ class EmployeeBackSearchFilter(EmployeeBackFilter): raise ValidationError({'detail': _('Type at least 3 characters to search please.')}) return queryset.trigram_search(value) return queryset + + +class MenuDishesBackFilter(filters.FilterSet): + """Menu filter set.""" + + category = filters.CharFilter(method='search_by_category') + is_drinks_included = filters.BooleanFilter(field_name='is_drinks_included') + establishment_id = filters.NumberFilter(field_name='establishment_id') + + class Meta: + """Meta class.""" + + model = models.Menu + fields = ( + 'category', + 'is_drinks_included', + 'establishment_id', + ) + + def search_by_category(self, queryset, name, value): + """Search by category.""" + if value not in EMPTY_VALUES: + return queryset.search_by_category(value) + return queryset diff --git a/apps/establishment/migrations/0079_auto_20200124_0720.py b/apps/establishment/migrations/0079_auto_20200124_0720.py new file mode 100644 index 00000000..01c4e509 --- /dev/null +++ b/apps/establishment/migrations/0079_auto_20200124_0720.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.7 on 2020-01-24 07:20 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('establishment', '0078_menu_old_id'), + ] + + operations = [ + migrations.AlterModelOptions( + name='menu', + options={'ordering': ('-created',), 'verbose_name': 'menu', 'verbose_name_plural': 'menu'}, + ), + migrations.AlterField( + model_name='plate', + name='menu', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='plates', to='establishment.Menu', verbose_name='menu'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 77f90c23..bae62a1a 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -1214,7 +1214,11 @@ class Plate(TranslatedFieldsMixin, models.Model): _('currency code'), max_length=250, blank=True, null=True, default=None) menu = models.ForeignKey( - 'establishment.Menu', verbose_name=_('menu'), on_delete=models.CASCADE) + 'establishment.Menu', + verbose_name=_('menu'), + related_name='plates', + on_delete=models.CASCADE, + ) @property def establishment_id(self): @@ -1225,6 +1229,27 @@ class Plate(TranslatedFieldsMixin, models.Model): verbose_name_plural = _('plates') +class MenuQuerySet(models.QuerySet): + def with_schedule_plates_establishment(self): + return self.select_related( + 'establishment', + ).prefetch_related( + 'schedule', + 'plates', + ) + + def dishes(self): + return self.filter( + Q(category__icontains='starter') | + Q(category__icontains='dessert') | + Q(category__icontains='main_course') + ) + + def search_by_category(self, value): + """Search by category.""" + return self.filter(category__icontains=value) + + class Menu(TranslatedFieldsMixin, BaseAttributes): """Menu model.""" @@ -1245,9 +1270,12 @@ class Menu(TranslatedFieldsMixin, BaseAttributes): ) old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) + objects = MenuQuerySet.as_manager() + class Meta: verbose_name = _('menu') verbose_name_plural = _('menu') + ordering = ('-created',) class MenuUploads(BaseAttributes): diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 4000bef9..147dd1c5 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -12,8 +12,9 @@ from location.models import Address from location.serializers import AddressDetailSerializer, TranslatedField from main.models import Currency from main.serializers import AwardSerializer +from timetable.serialziers import ScheduleRUDSerializer from utils.decorators import with_base_attributes -from utils.serializers import ImageBaseSerializer, TimeZoneChoiceField +from utils.serializers import ImageBaseSerializer, TimeZoneChoiceField, ProjectModelSerializer def phones_handler(phones_list, establishment): @@ -513,3 +514,33 @@ class EstablishmentAdminListSerializer(UserShortSerializer): 'username', 'email' ] + + +class _PlateSerializer(ProjectModelSerializer): + name_translated = TranslatedField() + + class Meta: + model = models.Plate + fields = [ + 'name_translated', + 'price', + ] + + +class MenuDishesSerializer(ProjectModelSerializer): + """for dessert, main_course and starter category""" + + schedule = ScheduleRUDSerializer(many=True, allow_null=True) + plates = _PlateSerializer(read_only=True, many=True, source='plate_set') + category_translated = serializers.CharField(read_only=True) + + class Meta: + model = models.Menu + fields = [ + 'id', + 'category', + 'category_translated', + 'establishment', + 'schedule', + 'plates', + ] diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 066452a7..cd60e9f1 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -24,6 +24,7 @@ from utils.serializers import (ProjectModelSerializer, TranslatedField, logger = logging.getLogger(__name__) + class ContactPhonesSerializer(serializers.ModelSerializer): """Contact phone serializer""" diff --git a/apps/establishment/urls/back.py b/apps/establishment/urls/back.py index 2de741c1..6899d1f0 100644 --- a/apps/establishment/urls/back.py +++ b/apps/establishment/urls/back.py @@ -30,6 +30,7 @@ urlpatterns = [ name='note-rud'), path('slug//admin/', views.EstablishmentAdminView.as_view(), name='establishment-admin-list'), + path('menus/dishes/', views.MenuDishesListCreateView.as_view(), name='menu-dishes-list'), path('menus/', views.MenuListCreateView.as_view(), name='menu-list'), path('menus//', views.MenuRUDView.as_view(), name='menu-rud'), path('plates/', views.PlateListCreateView.as_view(), name='plates'), diff --git a/apps/establishment/views/back.py b/apps/establishment/views/back.py index d39ce6b2..2610d967 100644 --- a/apps/establishment/views/back.py +++ b/apps/establishment/views/back.py @@ -1,6 +1,4 @@ """Establishment app views.""" -from django.core.exceptions import ObjectDoesNotExist -from django.http import Http404 from django.shortcuts import get_object_or_404 from django_filters.rest_framework import DjangoFilterBackend from rest_framework import generics, permissions @@ -417,3 +415,11 @@ class EstablishmentAdminView(generics.ListAPIView): establishment = get_object_or_404( models.Establishment, slug=self.kwargs['slug']) return User.objects.establishment_admin(establishment).distinct() + + +class MenuDishesListCreateView(generics.ListCreateAPIView): + """Menu (dessert, main_course, starter) list create view.""" + serializer_class = serializers.MenuDishesSerializer + queryset = models.Menu.objects.with_schedule_plates_establishment().dishes().distinct() + permission_classes = [IsWineryReviewer | IsEstablishmentManager] + filter_class = filters.MenuDishesBackFilter