"""Establishment app views.""" from django.db.models.query_utils import Q from django.db import transaction 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, response, status from rest_framework.response import Response from account.models import User from establishment import filters, models, serializers from establishment.models import EstablishmentEmployee, Menu from timetable.models import Timetable from timetable.serialziers import ScheduleCreateSerializer, ScheduleRUDSerializer from utils.methods import get_permission_classes from utils.permissions import (IsEstablishmentAdministrator, IsEstablishmentManager) from utils.views import CreateDestroyGalleryViewMixin class MenuRUDMixinViews: """Menu mixin""" def get_object(self): instance = self.get_queryset().filter( Q(establishment__slug=self.kwargs.get('slug')) | Q(establishment__id=self.kwargs.get('pk')) ).first() if instance is None: raise Http404 return instance class EstablishmentMixinViews: """Establishment mixin.""" def get_queryset(self): """Overridden method 'get_queryset'.""" queryset = models.Establishment.objects.with_base_related if hasattr(self, 'request') and \ (hasattr(self.request, 'user') and hasattr(self.request, 'country_code')): return queryset().available_establishments(self.request.user, self.request.country_code) return queryset().none() class EstablishmentListCreateView(EstablishmentMixinViews, generics.ListCreateAPIView): """Establishment list/create view.""" filter_class = filters.EstablishmentFilter serializer_class = serializers.EstablishmentListCreateSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class EmployeeEstablishmentPositionsView(generics.ListAPIView): """Establishment by employee view.""" queryset = models.EstablishmentEmployee.objects.all() serializer_class = serializers.EstablishmentEmployeePositionsSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) def get_queryset(self): employee_pk = self.kwargs.get('pk') return super().get_queryset().filter(employee__id=employee_pk).all().prefetch_related( 'establishment').select_related('position') class EmployeeEstablishmentsListView(generics.ListAPIView): """Establishment by employee list view.""" serializer_class = serializers.EstablishmentListCreateSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) def get_queryset(self): pk = self.kwargs.get('pk') employee = get_object_or_404(models.Employee, pk=pk) return employee.establishments.with_extended_related() class EmployeePositionsListView(generics.ListAPIView): """Establishment position by employee list view.""" queryset = models.Establishment.objects.all() serializer_class = serializers.EstablishmentPositionListSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) def get_queryset(self): pk = self.kwargs.get('pk') employee = get_object_or_404(models.Employee, pk=pk) return employee.establishments.with_extended_related() class EstablishmentRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView): lookup_field = 'slug' serializer_class = serializers.EstablishmentRUDSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) def get_queryset(self): """Overridden get_queryset method.""" qs = super(EstablishmentRUDView, self).get_queryset() return qs.prefetch_related( 'establishmentemployee_set', 'establishmentemployee_set__establishment', ) class EstablishmentScheduleRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView): """Establishment schedule RUD view""" lookup_field = 'slug' serializer_class = ScheduleRUDSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) def get_object(self): """ Returns the object the view is displaying. """ establishment_slug = self.kwargs['slug'] schedule_id = self.kwargs['schedule_id'] establishment = get_object_or_404(klass=super(EstablishmentScheduleRUDView, self).get_queryset(), slug=establishment_slug) schedule = get_object_or_404(klass=establishment.schedule, id=schedule_id) # May raise a permission denied self.check_object_permissions(self.request, establishment) self.check_object_permissions(self.request, schedule) return schedule class EstablishmentScheduleCreateView(generics.CreateAPIView): """Establishment schedule Create view""" lookup_field = 'slug' serializer_class = ScheduleCreateSerializer queryset = Timetable.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class MenuListCreateView(generics.ListCreateAPIView): """Menu list create view.""" serializer_class = serializers.MenuBackOfficeSerializer queryset = models.Menu.objects.with_base_related() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) filter_backends = (DjangoFilterBackend,) filterset_fields = ( 'establishment', 'establishment__slug', ) def create(self, request, *args, **kwargs): response_data = [] with transaction.atomic(): for menu in request.data: if 'id' in menu: instance = get_object_or_404(Menu, pk=menu['id']) serializer = self.get_serializer(instance, data=menu) else: serializer = self.get_serializer(data=menu) serializer.is_valid(raise_exception=True) serializer.save() response_data.append(serializer.data) return Response(response_data, status=status.HTTP_201_CREATED) class MenuRUDView(generics.RetrieveUpdateDestroyAPIView): """Menu RUD view.""" serializer_class = serializers.MenuRUDSerializers queryset = models.Menu.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class MenuUploadsRUDView(generics.RetrieveDestroyAPIView): """Menu uploads RUD view.""" serializer_class = serializers.MenuFilesSerializers queryset = models.MenuFiles.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class MenuUploadsCreateView(generics.CreateAPIView): """Menu uploads list view""" serializer_class = serializers.MenuFilesSerializers queryset = models.MenuFiles.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class SocialChoiceListCreateView(generics.ListCreateAPIView): """SocialChoice list create view.""" serializer_class = serializers.SocialChoiceSerializers queryset = models.SocialChoice.objects.all() pagination_class = None permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class SocialChoiceRUDView(generics.RetrieveUpdateDestroyAPIView): """SocialChoice RUD view.""" serializer_class = serializers.SocialChoiceSerializers queryset = models.SocialChoice.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class SocialListCreateView(generics.ListCreateAPIView): """Social list create view.""" serializer_class = serializers.SocialNetworkSerializers queryset = models.SocialNetwork.objects.all() pagination_class = None permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class SocialRUDView(generics.RetrieveUpdateDestroyAPIView): """Social RUD view.""" serializer_class = serializers.SocialNetworkSerializers queryset = models.SocialNetwork.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class PlateListCreateView(generics.ListCreateAPIView): """Plate list create view.""" serializer_class = serializers.PlatesSerializers queryset = models.Plate.objects.all() pagination_class = None permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) class PlateRUDView(generics.RetrieveUpdateDestroyAPIView): """Plate RUD view.""" serializer_class = serializers.PlatesSerializers queryset = models.Plate.objects.all() permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) class PhonesListCreateView(generics.ListCreateAPIView): """Phones list create view.""" serializer_class = serializers.ContactPhoneBackSerializers queryset = models.ContactPhone.objects.all() pagination_class = None permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) class PhonesRUDView(generics.RetrieveUpdateDestroyAPIView): """Phones RUD view.""" serializer_class = serializers.ContactPhoneBackSerializers queryset = models.ContactPhone.objects.all() permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) class EmailListCreateView(generics.ListCreateAPIView): """Email list create view.""" serializer_class = serializers.ContactEmailBackSerializers queryset = models.ContactEmail.objects.all() pagination_class = None permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) class EmailRUDView(generics.RetrieveUpdateDestroyAPIView): """Email RUD view.""" serializer_class = serializers.ContactEmailBackSerializers queryset = models.ContactEmail.objects.all() permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) class EmployeeListCreateView(generics.ListCreateAPIView): """Employee list create view.""" filter_class = filters.EmployeeBackFilter serializer_class = serializers.EmployeeBackSerializers queryset = models.Employee.objects.all().distinct().with_back_office_related() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class EmployeesListSearchViews(generics.ListAPIView): """Employee search view""" pagination_class = None queryset = models.Employee.objects.all().with_back_office_related().select_related('photo') filter_class = filters.EmployeeBackSearchFilter serializer_class = serializers.EmployeeBackSerializers permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class EstablishmentEmployeeListView(generics.ListCreateAPIView): """Establishment emplyoees list view.""" serializer_class = serializers.EstEmployeeBackSerializer pagination_class = None permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) def get_queryset(self): establishment_id = self.kwargs['establishment_id'] return models.Employee.objects.filter( establishmentemployee__establishment_id=establishment_id, ).distinct() class EmployeeRUDView(generics.RetrieveUpdateDestroyAPIView): """Employee RUD view.""" serializer_class = serializers.EmployeeBackSerializers queryset = models.Employee.objects.with_back_office_related() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator, ) class RemoveAwardView(generics.DestroyAPIView): lookup_field = 'pk' serializer_class = serializers.EmployeeBackSerializers queryset = models.Employee.objects.with_back_office_related() permission_classes = get_permission_classes() def get_object(self): employee = super().get_object() employee.remove_award(self.kwargs['award_id']) return employee def delete(self, request, *args, **kwargs): instance = self.get_object() return Response(status=status.HTTP_204_NO_CONTENT) class EstablishmentTypeListCreateView(generics.ListCreateAPIView): """Establishment type list/create view.""" serializer_class = serializers.EstablishmentTypeBaseSerializer queryset = models.EstablishmentType.objects.select_related('default_image') pagination_class = None permission_classes = get_permission_classes() class EstablishmentTypeRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment type retrieve/update/destroy view.""" serializer_class = serializers.EstablishmentTypeBaseSerializer queryset = models.EstablishmentType.objects.select_related('default_image') permission_classes = get_permission_classes() class EstablishmentSubtypeListCreateView(generics.ListCreateAPIView): """Establishment subtype list/create view.""" serializer_class = serializers.EstablishmentSubTypeBaseSerializer queryset = models.EstablishmentSubType.objects.select_related('default_image') pagination_class = None permission_classes = get_permission_classes() class EstablishmentSubtypeRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment subtype retrieve/update/destroy view.""" serializer_class = serializers.EstablishmentSubTypeBaseSerializer queryset = models.EstablishmentSubType.objects.select_related('default_image') permission_classes = get_permission_classes() class EstablishmentGalleryCreateDestroyView(EstablishmentMixinViews, CreateDestroyGalleryViewMixin): """Resource for a create|destroy gallery for establishment for back-office users.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentBackOfficeGallerySerializer permission_classes = get_permission_classes() def get_object(self): """ Returns the object the view is displaying. """ establishment_qs = self.filter_queryset(self.get_queryset()) establishment = get_object_or_404(establishment_qs, slug=self.kwargs.get('slug')) gallery = get_object_or_404(establishment.establishment_gallery, image_id=self.kwargs.get('image_id')) # May raise a permission denied self.check_object_permissions(self.request, gallery) return gallery class EstablishmentGalleryListView(EstablishmentMixinViews, generics.ListAPIView): """Resource for returning gallery for establishment for back-office users.""" lookup_field = 'slug' serializer_class = serializers.ImageBaseSerializer permission_classes = get_permission_classes() def get_object(self): """Override get_object method.""" qs = super(EstablishmentGalleryListView, self).get_queryset() establishment = get_object_or_404(qs, slug=self.kwargs.get('slug')) # May raise a permission denied self.check_object_permissions(self.request, establishment) return establishment def get_queryset(self): """Override get_queryset method.""" return self.get_object().crop_gallery class EstablishmentCompanyListCreateView(EstablishmentMixinViews, generics.ListCreateAPIView): """List|Create establishment company view.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentCompanyListCreateSerializer permission_classes = get_permission_classes() def get_object(self): """Returns the object the view is displaying.""" establishment_qs = super(EstablishmentCompanyListCreateView, self).get_queryset() filtered_qs = self.filter_queryset(establishment_qs) establishment = get_object_or_404(filtered_qs, slug=self.kwargs.get('slug')) # May raise a permission denied self.check_object_permissions(self.request, establishment) return establishment def get_queryset(self): """Overridden get_queryset method.""" return self.get_object().companies.all() class EstablishmentCompanyRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView): """Create|Retrieve|Update|Destroy establishment company view.""" lookup_field = 'slug' serializer_class = serializers.CompanyBaseSerializer permission_classes = get_permission_classes() def get_object(self): """Returns the object the view is displaying.""" establishment_qs = super(EstablishmentCompanyRUDView, self).get_queryset() filtered_ad_qs = self.filter_queryset(establishment_qs) establishment = get_object_or_404(filtered_ad_qs, slug=self.kwargs.get('slug')) company = get_object_or_404(establishment.companies.all(), pk=self.kwargs.get('company_pk')) # May raise a permission denied self.check_object_permissions(self.request, company) return company class EstablishmentNoteListCreateView(EstablishmentMixinViews, generics.ListCreateAPIView): """Retrieve|Update|Destroy establishment note view.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentNoteListCreateSerializer permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) def get_object(self): """Returns the object the view is displaying.""" establishment_qs = super(EstablishmentNoteListCreateView, self).get_queryset() filtered_establishment_qs = self.filter_queryset(establishment_qs) establishment = get_object_or_404(filtered_establishment_qs, slug=self.kwargs.get('slug')) # May raise a permission denied self.check_object_permissions(self.request, establishment) return establishment def get_queryset(self): """Overridden get_queryset method.""" return self.get_object().notes.all() class EstablishmentNoteRUDView(EstablishmentMixinViews, generics.RetrieveUpdateDestroyAPIView): """Create|Retrieve|Update|Destroy establishment note view.""" lookup_field = 'slug' serializer_class = serializers.EstablishmentNoteBaseSerializer permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager, ) def get_object(self): """Returns the object the view is displaying.""" establishment_qs = super(EstablishmentNoteRUDView, self).get_queryset() filtered_establishment_qs = self.filter_queryset(establishment_qs) establishment = get_object_or_404(filtered_establishment_qs, slug=self.kwargs.get('slug')) note = get_object_or_404(establishment.notes.all(), pk=self.kwargs['note_pk']) # May raise a permission denied self.check_object_permissions(self.request, note) return note class EstablishmentEmployeeCreateView(generics.CreateAPIView): serializer_class = serializers.EstablishmentEmployeeCreateSerializer queryset = models.EstablishmentEmployee.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) class EstablishmentEmployeeDeleteView(generics.DestroyAPIView): queryset = EstablishmentEmployee.objects.all() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) class EstablishmentPositionListView(generics.ListAPIView): """Establishment positions list view.""" pagination_class = None queryset = models.Position.objects.all() serializer_class = serializers.PositionBackSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) class EstablishmentAdminView(generics.ListAPIView): """Establishment admin list view.""" serializer_class = serializers.EstablishmentAdminListSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) def get_queryset(self): 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 = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) filter_class = filters.MenuDishesBackFilter class MenuDishesRUDView(generics.RetrieveUpdateDestroyAPIView): """Menu (dessert, main_course, starter) RUD view.""" serializer_class = serializers.MenuDishesRUDSerializers queryset = models.Menu.objects.dishes().distinct() permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) class MenuGalleryListView(generics.ListAPIView): """Resource for returning gallery for menu for back-office users.""" serializer_class = serializers.ImageBaseSerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) queryset = models.Menu.objects.with_schedule_plates_establishment().with_gallery().dishes() def get_object(self): """Override get_object method.""" qs = super(MenuGalleryListView, self).get_queryset() menu = get_object_or_404(qs, pk=self.kwargs.get('pk')) # May raise a permission denied # self.check_object_permissions(self.request, menu) return menu def get_queryset(self): """Override get_queryset method.""" return self.get_object().crop_gallery class MenuGalleryCreateDestroyView(CreateDestroyGalleryViewMixin): """Resource for a create gallery for menu for back-office users.""" serializer_class = serializers.MenuGallerySerializer permission_classes = get_permission_classes( IsEstablishmentManager, IsEstablishmentAdministrator ) def get_queryset(self): """Override get_queryset method.""" qs = models.Menu.objects.with_schedule_plates_establishment().with_gallery().dishes() return qs def create(self, request, *args, **kwargs): _ = super().create(request, *args, **kwargs) news_qs = self.filter_queryset(self.get_queryset()) return response.Response( data=serializers.MenuDishesRUDSerializers(get_object_or_404(news_qs, pk=kwargs.get('pk'))).data ) def get_object(self): """ Returns the object the view is displaying. """ menu_qs = self.filter_queryset(self.get_queryset()) menu = get_object_or_404(menu_qs, pk=self.kwargs.get('pk')) gallery = get_object_or_404(menu.menu_gallery, image_id=self.kwargs.get('image_id')) # May raise a permission denied self.check_object_permissions(self.request, gallery) return gallery