diff --git a/apps/account/views/common.py b/apps/account/views/common.py index d29ce2bb..8b066742 100644 --- a/apps/account/views/common.py +++ b/apps/account/views/common.py @@ -63,7 +63,7 @@ class SendConfirmationEmailView(generics.GenericAPIView): return Response(status=status.HTTP_200_OK) -class ConfirmEmailView(JWTGenericViewMixin): +class ConfirmEmailView(JWTGenericViewMixin, generics.GenericAPIView): """View for confirm changing email""" permission_classes = (permissions.AllowAny,) diff --git a/apps/account/views/web.py b/apps/account/views/web.py index 9f2ebcfd..0fc762f5 100644 --- a/apps/account/views/web.py +++ b/apps/account/views/web.py @@ -33,7 +33,7 @@ class PasswordResetView(generics.GenericAPIView): return Response(status=status.HTTP_200_OK) -class PasswordResetConfirmView(JWTGenericViewMixin): +class PasswordResetConfirmView(JWTGenericViewMixin, generics.GenericAPIView): """View for confirmation new password""" serializer_class = serializers.PasswordResetConfirmSerializer permission_classes = (permissions.AllowAny,) diff --git a/apps/advertisement/views/back.py b/apps/advertisement/views/back.py index d11615ba..a2973589 100644 --- a/apps/advertisement/views/back.py +++ b/apps/advertisement/views/back.py @@ -45,7 +45,7 @@ class AdvertisementPageListCreateView(AdvertisementBackOfficeViewMixin, ad_qs = Advertisement.objects.all() filtered_ad_qs = self.filter_queryset(ad_qs) - ad = get_object_or_404(filtered_ad_qs, pk=self.kwargs['pk']) + ad = get_object_or_404(filtered_ad_qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, ad) @@ -68,8 +68,8 @@ class AdvertisementPageRUDView(AdvertisementBackOfficeViewMixin, ad_qs = Advertisement.objects.all() filtered_ad_qs = self.filter_queryset(ad_qs) - ad = get_object_or_404(filtered_ad_qs, pk=self.kwargs['ad_pk']) - page = get_object_or_404(ad.pages.all(), pk=self.kwargs['page_pk']) + ad = get_object_or_404(filtered_ad_qs, pk=self.kwargs.get('ad_pk')) + page = get_object_or_404(ad.pages.all(), pk=self.kwargs.get('page_pk')) # May raise a permission denied self.check_object_permissions(self.request, page) diff --git a/apps/authorization/views/common.py b/apps/authorization/views/common.py index 9d2069f2..8b466acb 100644 --- a/apps/authorization/views/common.py +++ b/apps/authorization/views/common.py @@ -71,7 +71,7 @@ class OAuth2ViewMixin(CsrfExemptMixin, OAuthLibMixin, BaseOAuth2ViewMixin): # Sign in via Facebook -class OAuth2SignUpView(OAuth2ViewMixin, JWTGenericViewMixin): +class OAuth2SignUpView(OAuth2ViewMixin, JWTGenericViewMixin, generics.GenericAPIView): """ Implements an endpoint to convert a provider token to an access token @@ -142,7 +142,7 @@ class SignUpView(generics.GenericAPIView): return Response(status=status.HTTP_201_CREATED) -class ConfirmationEmailView(JWTGenericViewMixin): +class ConfirmationEmailView(JWTGenericViewMixin, generics.GenericAPIView): """View for confirmation email""" permission_classes = (permissions.AllowAny, ) @@ -174,7 +174,7 @@ class ConfirmationEmailView(JWTGenericViewMixin): # Login by username|email + password -class LoginByUsernameOrEmailView(JWTGenericViewMixin): +class LoginByUsernameOrEmailView(JWTGenericViewMixin, generics.GenericAPIView): """Login by email and password""" permission_classes = (permissions.AllowAny,) serializer_class = serializers.LoginByUsernameOrEmailSerializer @@ -197,7 +197,7 @@ class LoginByUsernameOrEmailView(JWTGenericViewMixin): # Logout -class LogoutView(JWTGenericViewMixin): +class LogoutView(JWTGenericViewMixin, generics.GenericAPIView): """Logout user""" permission_classes = (IsAuthenticatedAndTokenIsValid, ) @@ -215,7 +215,7 @@ class LogoutView(JWTGenericViewMixin): # Refresh token -class RefreshTokenView(JWTGenericViewMixin): +class RefreshTokenView(JWTGenericViewMixin, generics.GenericAPIView): """Refresh access_token""" permission_classes = (permissions.AllowAny, ) serializer_class = serializers.RefreshTokenSerializer diff --git a/apps/establishment/admin.py b/apps/establishment/admin.py index e6b0d991..45716f32 100644 --- a/apps/establishment/admin.py +++ b/apps/establishment/admin.py @@ -7,7 +7,7 @@ from comment.models import Comment from utils.admin import BaseModelAdminMixin from establishment import models from main.models import Award -from product.models import Product +from product.models import Product, PurchasedProduct from review import models as review_models @@ -69,13 +69,19 @@ class EstablishmentNote(admin.TabularInline): extra = 0 +class PurchasedProduct(admin.TabularInline): + model = PurchasedProduct + extra = 0 + + @admin.register(models.Establishment) class EstablishmentAdmin(BaseModelAdminMixin, admin.ModelAdmin): """Establishment admin.""" list_display = ['id', '__str__', 'image_tag', ] search_fields = ['id', 'name', 'index_name', 'slug'] list_filter = ['public_mark', 'toque_number'] - inlines = [GalleryImageInline, CompanyInline, EstablishmentNote] + inlines = [GalleryImageInline, CompanyInline, EstablishmentNote, + PurchasedProduct] # inlines = [ # AwardInline, ContactPhoneInline, ContactEmailInline, diff --git a/apps/establishment/migrations/0065_establishment_purchased_products.py b/apps/establishment/migrations/0065_establishment_purchased_products.py new file mode 100644 index 00000000..25088455 --- /dev/null +++ b/apps/establishment/migrations/0065_establishment_purchased_products.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.7 on 2019-11-20 12:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('product', '0018_purchasedproduct'), + ('establishment', '0064_auto_20191119_1546'), + ] + + operations = [ + migrations.AddField( + model_name='establishment', + name='purchased_products', + field=models.ManyToManyField(blank=True, help_text='Attribute from legacy db.\nMust be deleted after the implementation of the market.', related_name='establishments', through='product.PurchasedProduct', to='product.Product', verbose_name='purchased plaques'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 3aee6c31..26046953 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -397,6 +397,13 @@ class Establishment(GalleryModelMixin, ProjectBaseMixin, URLImageMixin, Translat currency = models.ForeignKey(Currency, blank=True, null=True, default=None, on_delete=models.PROTECT, verbose_name=_('currency')) + purchased_products = models.ManyToManyField('product.Product', blank=True, + through='product.PurchasedProduct', + related_name='establishments', + verbose_name=_('purchased plaques'), + help_text=_('Attribute from legacy db.\n' + 'Must be deleted after the ' + 'implementation of the market.')) objects = EstablishmentQuerySet.as_manager() @@ -409,6 +416,12 @@ class Establishment(GalleryModelMixin, ProjectBaseMixin, URLImageMixin, Translat def __str__(self): return f'id:{self.id}-{self.name}' + def clean_fields(self, exclude=None): + super().clean_fields(exclude) + if self.purchased_products.filter(product_type__index_name='souvenir').exists(): + raise ValidationError( + _('Only souvenirs.')) + def delete(self, using=None, keep_parents=False): """Overridden delete method""" # Delete all related companies diff --git a/apps/establishment/transfer_data.py b/apps/establishment/transfer_data.py index b3dc58f9..741a9989 100644 --- a/apps/establishment/transfer_data.py +++ b/apps/establishment/transfer_data.py @@ -4,7 +4,9 @@ from django.db.models import Q, F from establishment.models import Establishment from location.models import Address -from transfer.models import Establishments, Dishes, EstablishmentNotes +from product.models import PurchasedProduct, Product +from transfer.models import Establishments, Dishes, EstablishmentNotes, \ + EstablishmentMerchandises from transfer.serializers.establishment import EstablishmentSerializer, \ EstablishmentNoteSerializer from transfer.serializers.plate import PlateSerializer @@ -140,6 +142,43 @@ def transfer_establishment_note(): pprint(f"transfer_establishment_note errors: {errors}") +def transfer_purchased_plaques(): + update_products_counter = 0 + already_updated_counter = 0 + not_existed_establishment_counter = 0 + + purchased = EstablishmentMerchandises.objects.values_list( + 'establishment_id', + 'merchandise__vintage', + 'gifted', + 'quantity' + ) + for old_est_id, vintage, gifted, quantity in purchased: + establishment_qs = Establishment.objects.filter(old_id=old_est_id) + product_qs = Product.objects.filter(name='Plaque restaurants', + vintage=vintage) + if establishment_qs.exists() and product_qs.exists(): + product = product_qs.first() + establishment = establishment_qs.first() + + purchases, created = PurchasedProduct.objects.get_or_create( + establishment=establishment, + product=product, + is_gifted=gifted, + quantity=quantity + ) + if created: + update_products_counter += 1 + else: + already_updated_counter += 1 + else: + not_existed_establishment_counter += 1 + + print(f'Updated products: {update_products_counter}\n' + f'Already updated: {already_updated_counter}\n' + f'Not existed establishment: {not_existed_establishment_counter}') + + data_types = { "establishment": [ transfer_establishment, @@ -149,4 +188,7 @@ data_types = { transfer_establishment_addresses ], "menu": [transfer_menu], + "purchased_plaques": [ + transfer_purchased_plaques + ], } diff --git a/apps/establishment/views/back.py b/apps/establishment/views/back.py index ad38e806..d1897397 100644 --- a/apps/establishment/views/back.py +++ b/apps/establishment/views/back.py @@ -6,6 +6,7 @@ from establishment import filters, models, serializers from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer from utils.permissions import IsCountryAdmin, IsEstablishmentManager from utils.views import CreateDestroyGalleryViewMixin +from timetable.models import Timetable from rest_framework import status from rest_framework.response import Response @@ -36,13 +37,14 @@ class EstablishmentRUDView(generics.RetrieveUpdateDestroyAPIView): class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView): """Establishment schedule RUD view""" serializer_class = ScheduleRUDSerializer + permission_classes = [IsEstablishmentManager] def get_object(self): """ Returns the object the view is displaying. """ - establishment_pk = self.kwargs['pk'] - schedule_id = self.kwargs['schedule_id'] + establishment_pk = self.kwargs.get('pk') + schedule_id = self.kwargs.get('schedule_id') establishment = get_object_or_404(klass=models.Establishment.objects.all(), pk=establishment_pk) @@ -59,6 +61,8 @@ class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView): class EstablishmentScheduleCreateView(generics.CreateAPIView): """Establishment schedule Create view""" serializer_class = ScheduleCreateSerializer + queryset = Timetable.objects.all() + permission_classes = [IsEstablishmentManager] class MenuListCreateView(generics.ListCreateAPIView): @@ -200,8 +204,9 @@ class EstablishmentGalleryCreateDestroyView(EstablishmentMixinViews, """ establishment_qs = self.filter_queryset(self.get_queryset()) - establishment = get_object_or_404(establishment_qs, pk=self.kwargs['pk']) - gallery = get_object_or_404(establishment.establishment_gallery, image_id=self.kwargs['image_id']) + establishment = get_object_or_404(establishment_qs, pk=self.kwargs.get('pk')) + 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) @@ -217,7 +222,7 @@ class EstablishmentGalleryListView(EstablishmentMixinViews, def get_object(self): """Override get_object method.""" qs = super(EstablishmentGalleryListView, self).get_queryset() - establishment = get_object_or_404(qs, pk=self.kwargs['pk']) + establishment = get_object_or_404(qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, establishment) @@ -240,7 +245,7 @@ class EstablishmentCompanyListCreateView(EstablishmentMixinViews, establishment_qs = models.Establishment.objects.all() filtered_ad_qs = self.filter_queryset(establishment_qs) - establishment = get_object_or_404(filtered_ad_qs, pk=self.kwargs['pk']) + establishment = get_object_or_404(filtered_ad_qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, establishment) @@ -263,8 +268,8 @@ class EstablishmentCompanyRUDView(EstablishmentMixinViews, establishment_qs = models.Establishment.objects.all() filtered_ad_qs = self.filter_queryset(establishment_qs) - establishment = get_object_or_404(filtered_ad_qs, pk=self.kwargs['pk']) - company = get_object_or_404(establishment.companies.all(), pk=self.kwargs['company_pk']) + establishment = get_object_or_404(filtered_ad_qs, pk=self.kwargs.get('pk')) + 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) @@ -273,7 +278,7 @@ class EstablishmentCompanyRUDView(EstablishmentMixinViews, class EstablishmentNoteListCreateView(EstablishmentMixinViews, - generics.ListCreateAPIView): + generics.ListCreateAPIView): """Retrieve|Update|Destroy establishment note view.""" serializer_class = serializers.EstablishmentNoteListCreateSerializer @@ -283,7 +288,7 @@ class EstablishmentNoteListCreateView(EstablishmentMixinViews, establishment_qs = models.Establishment.objects.all() filtered_establishment_qs = self.filter_queryset(establishment_qs) - establishment = get_object_or_404(filtered_establishment_qs, pk=self.kwargs['pk']) + establishment = get_object_or_404(filtered_establishment_qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, establishment) @@ -306,7 +311,7 @@ class EstablishmentNoteRUDView(EstablishmentMixinViews, establishment_qs = models.Establishment.objects.all() filtered_establishment_qs = self.filter_queryset(establishment_qs) - establishment = get_object_or_404(filtered_establishment_qs, pk=self.kwargs['pk']) + establishment = get_object_or_404(filtered_establishment_qs, pk=self.kwargs.get('pk')) note = get_object_or_404(establishment.notes.all(), pk=self.kwargs['note_pk']) # May raise a permission denied diff --git a/apps/location/views/back.py b/apps/location/views/back.py index b6677837..4d420154 100644 --- a/apps/location/views/back.py +++ b/apps/location/views/back.py @@ -51,8 +51,8 @@ class CityGalleryCreateDestroyView(common.CityViewMixin, """ city_qs = self.filter_queryset(self.get_queryset()) - city = get_object_or_404(city_qs, pk=self.kwargs['pk']) - gallery = get_object_or_404(city.city_gallery, image_id=self.kwargs['image_id']) + city = get_object_or_404(city_qs, pk=self.kwargs.get('pk')) + gallery = get_object_or_404(city.city_gallery, image_id=self.kwargs.get('image_id')) # May raise a permission denied self.check_object_permissions(self.request, gallery) diff --git a/apps/news/views.py b/apps/news/views.py index 3e841246..638f208b 100644 --- a/apps/news/views.py +++ b/apps/news/views.py @@ -108,8 +108,8 @@ class NewsBackOfficeGalleryCreateDestroyView(NewsBackOfficeMixinView, """ news_qs = self.filter_queryset(self.get_queryset()) - news = get_object_or_404(news_qs, pk=self.kwargs['pk']) - gallery = get_object_or_404(news.news_gallery, image_id=self.kwargs['image_id']) + news = get_object_or_404(news_qs, pk=self.kwargs.get('pk')) + gallery = get_object_or_404(news.news_gallery, image_id=self.kwargs.get('image_id')) # May raise a permission denied self.check_object_permissions(self.request, gallery) @@ -125,7 +125,7 @@ class NewsBackOfficeGalleryListView(NewsBackOfficeMixinView, def get_object(self): """Override get_object method.""" qs = super(NewsBackOfficeGalleryListView, self).get_queryset() - news = get_object_or_404(qs, pk=self.kwargs['pk']) + news = get_object_or_404(qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, news) @@ -160,7 +160,7 @@ class NewsFavoritesCreateDestroyView(generics.CreateAPIView, generics.DestroyAPI """ Returns the object the view is displaying. """ - news = get_object_or_404(models.News, slug=self.kwargs['slug']) + news = get_object_or_404(models.News, slug=self.kwargs.get('slug')) favorites = get_object_or_404(news.favorites.filter(user=self.request.user)) # May raise a permission denied self.check_object_permissions(self.request, favorites) diff --git a/apps/product/migrations/0018_purchasedproduct.py b/apps/product/migrations/0018_purchasedproduct.py new file mode 100644 index 00000000..b1c23646 --- /dev/null +++ b/apps/product/migrations/0018_purchasedproduct.py @@ -0,0 +1,30 @@ +# Generated by Django 2.2.7 on 2019-11-20 12:49 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('establishment', '0064_auto_20191119_1546'), + ('product', '0017_auto_20191119_1546'), + ] + + operations = [ + migrations.CreateModel( + name='PurchasedProduct', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_gifted', models.NullBooleanField(default=None, verbose_name='is gifted')), + ('quantity', models.PositiveSmallIntegerField(verbose_name='quantity')), + ('establishment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='purchased_plaques', to='establishment.Establishment', verbose_name='establishment')), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='purchased_by_establishments', to='product.Product', verbose_name='plaque')), + ], + options={ + 'verbose_name': 'purchased plaque', + 'verbose_name_plural': 'purchased plaques', + 'unique_together': {('establishment', 'product')}, + }, + ), + ] diff --git a/apps/product/models.py b/apps/product/models.py index 6baaf43e..e562e4a3 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -263,12 +263,17 @@ class Product(GalleryModelMixin, TranslatedFieldsMixin, BaseAttributes, HasTagsM def grape_variety(self): return self.tags.filter(category__index_name='grape-variety') + @property + def bottle_sizes(self): + return self.tags.filter(category__index_name='bottle_size') + @property def related_tags(self): return super().visible_tags.exclude(category__index_name__in=[ 'sugar-content', 'wine-color', 'bottles-produced', - 'serial-number', 'grape-variety'] - ) + 'serial-number', 'grape-variety', 'serial_number', + 'alcohol_percentage', 'bottle_size', + ]) @property def display_name(self): @@ -315,6 +320,26 @@ class OnlineProduct(Product): verbose_name_plural = _('Online products') +class PurchasedProduct(models.Model): + """Model for storing establishment purchased plaques.""" + + establishment = models.ForeignKey('establishment.Establishment', on_delete=models.CASCADE, + related_name='purchased_plaques', + verbose_name=_('establishment')) + product = models.ForeignKey('product.Product', on_delete=models.CASCADE, + related_name='purchased_by_establishments', + verbose_name=_('plaque')) + is_gifted = models.NullBooleanField(default=None, + verbose_name=_('is gifted')) + quantity = models.PositiveSmallIntegerField(verbose_name=_('quantity')) + + class Meta: + """Meta class.""" + verbose_name = _('purchased plaque') + verbose_name_plural = _('purchased plaques') + unique_together = ('establishment', 'product') + + class Unit(models.Model): """Product unit model.""" name = models.CharField(max_length=255, diff --git a/apps/product/views/back.py b/apps/product/views/back.py index ac780849..fc5e108f 100644 --- a/apps/product/views/back.py +++ b/apps/product/views/back.py @@ -57,8 +57,8 @@ class ProductBackOfficeGalleryCreateDestroyView(ProductBackOfficeMixinView, """ product_qs = self.filter_queryset(self.get_queryset()) - product = get_object_or_404(product_qs, pk=self.kwargs['pk']) - gallery = get_object_or_404(product.product_gallery, image_id=self.kwargs['image_id']) + 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) @@ -75,7 +75,7 @@ class ProductBackOfficeGalleryListView(ProductBackOfficeMixinView, def get_object(self): """Override get_object method.""" qs = super(ProductBackOfficeGalleryListView, self).get_queryset() - product = get_object_or_404(qs, pk=self.kwargs['pk']) + product = get_object_or_404(qs, pk=self.kwargs.get('pk')) # May raise a permission denied self.check_object_permissions(self.request, product) @@ -149,7 +149,7 @@ class ProductNoteListCreateView(ProductBackOfficeMixinView, product_qs = models.Product.objects.all() filtered_product_qs = self.filter_queryset(product_qs) - product = get_object_or_404(filtered_product_qs, pk=self.kwargs['pk']) + 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) @@ -173,8 +173,8 @@ class ProductNoteRUDView(ProductBackOfficeMixinView, product_qs = models.Product.objects.all() filtered_product_qs = self.filter_queryset(product_qs) - product = get_object_or_404(filtered_product_qs, pk=self.kwargs['pk']) - note = get_object_or_404(product.notes.all(), pk=self.kwargs['note_pk']) + 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) diff --git a/apps/timetable/serialziers.py b/apps/timetable/serialziers.py index 37725e1d..533bca70 100644 --- a/apps/timetable/serialziers.py +++ b/apps/timetable/serialziers.py @@ -8,6 +8,9 @@ from timetable.models import Timetable class ScheduleRUDSerializer(serializers.ModelSerializer): """Serializer for Establishment model.""" + NULLABLE_FIELDS = ['lunch_start', 'lunch_end', 'dinner_start', + 'dinner_end', 'opening_at', 'closed_at'] + weekday_display = serializers.CharField(source='get_weekday_display', read_only=True) @@ -18,9 +21,6 @@ class ScheduleRUDSerializer(serializers.ModelSerializer): opening_at = serializers.TimeField(required=False) closed_at = serializers.TimeField(required=False) - NULLABLE_FIELDS = ['lunch_start', 'lunch_end', 'dinner_start', - 'dinner_end', 'opening_at', 'closed_at'] - class Meta: """Meta class.""" model = Timetable diff --git a/apps/transfer/management/commands/transfer.py b/apps/transfer/management/commands/transfer.py index d69dd908..9126856f 100644 --- a/apps/transfer/management/commands/transfer.py +++ b/apps/transfer/management/commands/transfer.py @@ -39,6 +39,7 @@ class Command(BaseCommand): 'rating_count', 'product_review', 'newsletter_subscriber', # подписчики на рассылку - переносить после переноса пользователей №1 + 'purchased_plaques', # №6 - перенос купленных тарелок ] def handle(self, *args, **options): diff --git a/apps/transfer/models.py b/apps/transfer/models.py index d8be36ce..f4a1a800 100644 --- a/apps/transfer/models.py +++ b/apps/transfer/models.py @@ -581,22 +581,19 @@ class EstablishmentInfos(MigrateMixin): db_table = 'establishment_infos' -# class EstablishmentMerchandises(MigrateMixin): -# using = 'legacy' -# -# establishment = models.ForeignKey('Establishments', models.DO_NOTHING, blank=True, null=True) +class EstablishmentMerchandises(MigrateMixin): + using = 'legacy' -# TODO: модели Merchandises нету в гугл таблице Check Migrations + establishment = models.ForeignKey('Establishments', models.DO_NOTHING, blank=True, null=True) + merchandise = models.ForeignKey('Merchandise', models.DO_NOTHING, blank=True, null=True) + gifted = models.NullBooleanField(blank=True, null=True) + quantity = models.IntegerField(blank=True, null=True) + created_at = models.DateTimeField() + updated_at = models.DateTimeField() -# merchandise = models.ForeignKey('Merchandises', models.DO_NOTHING, blank=True, null=True) -# gifted = models.IntegerField(blank=True, null=True) -# quantity = models.IntegerField(blank=True, null=True) -# created_at = models.DateTimeField() -# updated_at = models.DateTimeField() -# -# class Meta: -# managed = False -# db_table = 'establishment_merchandises' + class Meta: + managed = False + db_table = 'establishment_merchandises' class Menus(MigrateMixin): diff --git a/apps/transfer/serializers/product.py b/apps/transfer/serializers/product.py index a0f3ef8a..86c6720a 100644 --- a/apps/transfer/serializers/product.py +++ b/apps/transfer/serializers/product.py @@ -265,7 +265,7 @@ class ProductSerializer(TransferSerializerMixin): state = serializers.CharField() bottles_produced = serializers.CharField(allow_null=True, allow_blank=True) unique_key = serializers.CharField(allow_null=True) - price = serializers.DecimalField(max_digits=14, decimal_places=2) + price = serializers.DecimalField(max_digits=14, decimal_places=2, allow_null=True) class Meta: model = models.Product diff --git a/apps/utils/views.py b/apps/utils/views.py index 870e132f..a8580f59 100644 --- a/apps/utils/views.py +++ b/apps/utils/views.py @@ -12,7 +12,7 @@ from gallery.tasks import delete_image # JWT # Login base view mixins -class JWTGenericViewMixin(generics.GenericAPIView): +class JWTGenericViewMixin: """JWT view mixin""" ACCESS_TOKEN_HTTP_ONLY = False @@ -39,30 +39,31 @@ class JWTGenericViewMixin(generics.GenericAPIView): """ COOKIES = [] - if hasattr(self.request, 'locale'): - COOKIES.append(self.COOKIE(key='locale', - value=self.request.locale, - http_only=self.ACCESS_TOKEN_HTTP_ONLY, - secure=self.LOCALE_SECURE, - max_age=settings.COOKIES_MAX_AGE if permanent else None)) - if hasattr(self.request, 'country_code'): - COOKIES.append(self.COOKIE(key='country_code', - value=self.request.country_code, - http_only=self.COUNTRY_CODE_HTTP_ONLY, - secure=self.COUNTRY_CODE_SECURE, - max_age=settings.COOKIES_MAX_AGE if permanent else None)) - if access_token: - COOKIES.append(self.COOKIE(key='access_token', - value=access_token, - http_only=self.ACCESS_TOKEN_HTTP_ONLY, - secure=self.ACCESS_TOKEN_SECURE, - max_age=settings.COOKIES_MAX_AGE if permanent else None)) - if refresh_token: - COOKIES.append(self.COOKIE(key='refresh_token', - value=refresh_token, - http_only=self.REFRESH_TOKEN_HTTP_ONLY, - secure=self.REFRESH_TOKEN_SECURE, - max_age=settings.COOKIES_MAX_AGE if permanent else None)) + if hasattr(self, 'request'): + if hasattr(self.request, 'locale'): + COOKIES.append(self.COOKIE(key='locale', + value=self.request.locale, + http_only=self.ACCESS_TOKEN_HTTP_ONLY, + secure=self.LOCALE_SECURE, + max_age=settings.COOKIES_MAX_AGE if permanent else None)) + if hasattr(self.request, 'country_code'): + COOKIES.append(self.COOKIE(key='country_code', + value=self.request.country_code, + http_only=self.COUNTRY_CODE_HTTP_ONLY, + secure=self.COUNTRY_CODE_SECURE, + max_age=settings.COOKIES_MAX_AGE if permanent else None)) + if access_token: + COOKIES.append(self.COOKIE(key='access_token', + value=access_token, + http_only=self.ACCESS_TOKEN_HTTP_ONLY, + secure=self.ACCESS_TOKEN_SECURE, + max_age=settings.COOKIES_MAX_AGE if permanent else None)) + if refresh_token: + COOKIES.append(self.COOKIE(key='refresh_token', + value=refresh_token, + http_only=self.REFRESH_TOKEN_HTTP_ONLY, + secure=self.REFRESH_TOKEN_SECURE, + max_age=settings.COOKIES_MAX_AGE if permanent else None)) return COOKIES def _put_cookies_in_response(self, cookies: list, response: Response):