"""Product app back-office views.""" from django.shortcuts import get_object_or_404 from rest_framework import generics, status from rest_framework.response import Response from product import serializers, models from product.views import ProductBaseView from utils.methods import get_permission_classes from utils.permissions import ( IsEstablishmentManager, IsEstablishmentAdministrator) from utils.serializers import ImageBaseSerializer from utils.views import CreateDestroyGalleryViewMixin class ProductBackOfficeMixinView(ProductBaseView): """Product back-office mixin view.""" permission_classes = get_permission_classes( IsEstablishmentAdministrator, IsEstablishmentManager ) def get_queryset(self): """Override get_queryset method.""" queryset = ( models.Product.objects.with_base_related() .with_extended_related() .annotate_in_favorites(self.request.user) ) if hasattr(self, 'request') and \ (hasattr(self.request, 'user') and hasattr(self.request, 'country_code')): return queryset.available_products(self.request.user, self.request.country_code) return queryset.none() class ProductTypeBackOfficeMixinView: """Product type back-office mixin view.""" permission_classes = get_permission_classes() queryset = models.ProductType.objects.all() class ProductSubTypeBackOfficeMixinView: """Product sub type back-office mixin view.""" permission_classes = get_permission_classes() queryset = models.ProductSubType.objects.all() class ProductBackOfficeGalleryCreateDestroyView(ProductBackOfficeMixinView, CreateDestroyGalleryViewMixin): """ ## Product gallery image Create/Destroy view ### *POST* #### Description Attaching existing **image** by `image identifier` to **product** by `product identifier` in request kwargs. ##### Request ``` No body ``` ##### Response E.g.: ``` No content ``` ### *DELETE* #### Description Delete existing **gallery image** from **product** gallery, by `image identifier` and `product identifier` in request kwargs. **Note**: > Image wouldn't be deleted after all. ##### Request ``` No body ``` ##### Response ``` No content ``` """ serializer_class = serializers.ProductBackOfficeGallerySerializer def get_object(self): """ Returns the object the view is displaying. """ product_qs = self.get_queryset() product = get_object_or_404(product_qs, pk=self.kwargs.get('pk')) gallery = get_object_or_404(product.product_gallery, image_id=self.kwargs.get('image_id')) # May raise a permission denied self.check_object_permissions(self.request, gallery) return gallery class ProductBackOfficeGalleryListView(ProductBackOfficeMixinView, generics.ListAPIView): """ ## Product gallery image list view ### *GET* #### Description Returning paginated list of product images by `product identifier`, with cropped images. ##### Response E.g.: ``` { "count": 1, "next": null, "previous": null, "results": [ { "id": 11, ... } ] } ``` """ serializer_class = ImageBaseSerializer def get_object(self): """Override get_object method.""" qs = super(ProductBackOfficeGalleryListView, self).get_queryset() product = get_object_or_404(qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, product) return product def get_queryset(self): """Override get_queryset method.""" return self.get_object().crop_gallery class ProductDetailBackOfficeView(ProductBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """ Product back-office R/U/D view. **GET** ``` Implement getting ProductBackOffice object. ``` **PUT** ``` Implement updating ProductBackOffice. ``` **PATCH** ``` Implement partial updating ProductBackOffice. ``` **DELETE** ``` Implement deleting ProductBackOffice. ``` """ serializer_class = serializers.ProductBackOfficeDetailSerializer class ProductListCreateBackOfficeView(ProductBackOfficeMixinView, generics.ListCreateAPIView): """ Product back-office list-create view. **GET** ``` Implement getting product back-office list. ``` **POST** ``` Implement creating product back-office. ``` """ serializer_class = serializers.ProductBackOfficeDetailSerializer class ProductTypeListCreateBackOfficeView(ProductTypeBackOfficeMixinView, generics.ListCreateAPIView): """ Product type back-office list-create view. **GET** ``` Implement getting ProductType list. ``` **POST** ``` Implement creating ProductType. ``` """ serializer_class = serializers.ProductTypeBackOfficeDetailSerializer class ProductTypeRUDBackOfficeView(ProductTypeBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """ Product type back-office retrieve-update-destroy view. **GET** ``` Implement getting ProductType object. ``` **PUT** ``` Implement updating ProductType. ``` **PATCH** ``` Implement partial updating ProductType. ``` **DELETE** ``` Implement deleting ProductType. ``` """ serializer_class = serializers.ProductTypeBackOfficeDetailSerializer class ProductTypeTagCategoryCreateBackOfficeView(ProductTypeBackOfficeMixinView, generics.CreateAPIView): """View for attaching tag category to product type.""" serializer_class = serializers.ProductTypeTagCategorySerializer def create(self, request, *args, **kwargs): """ Implement creating ProductTypeTagCategory. """ super().create(request, *args, **kwargs) return Response(status=status.HTTP_201_CREATED) class ProductSubTypeListCreateBackOfficeView(ProductSubTypeBackOfficeMixinView, generics.ListCreateAPIView): """ Product sub type back-office list-create view. **GET** ``` Implement getting product sub type back-office list. ``` **POST** ``` Implement creating product sub type back-office. ``` """ serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer class ProductSubTypeRUDBackOfficeView(ProductSubTypeBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """ Product sub type back-office retrieve-update-destroy view. **GET** ``` Implement getting object Product sub type back-office. ``` **PUT** ``` Implement updating Product sub type back-office. ``` **PATCH** ``` Implement partial updating Product sub type back-office. ``` **DELETE** ``` Implement deleting Product sub type back office ``` """ serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer class ProductNoteListCreateView(ProductBackOfficeMixinView, generics.ListCreateAPIView): """Retrieve|Update|Destroy product note view.""" serializer_class = serializers.ProductNoteListCreateSerializer def get_object(self): """Returns the object the view is displaying.""" product_qs = super(ProductNoteListCreateView, self).get_queryset() filtered_product_qs = self.filter_queryset(product_qs) product = get_object_or_404(filtered_product_qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, product) return product def get_queryset(self): """Overridden get_queryset method.""" return self.get_object().notes.all() class ProductNoteRUDView(ProductBackOfficeMixinView, generics.RetrieveUpdateDestroyAPIView): """Create|Retrieve|Update|Destroy product note view.""" serializer_class = serializers.ProductNoteBaseSerializer def get_object(self): """Returns the object the view is displaying.""" product_qs = super(ProductNoteRUDView, self).get_queryset() filtered_product_qs = self.filter_queryset(product_qs) product = get_object_or_404(filtered_product_qs, pk=self.kwargs.get('pk')) note = get_object_or_404(product.notes.all(), pk=self.kwargs.get('note_pk')) # May raise a permission denied self.check_object_permissions(self.request, note) return note