From 13cc40c19c7e054cbd95be58052a5b17e480cea7 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Thu, 30 Jan 2020 16:17:19 +0300 Subject: [PATCH] added transfer for table - a la cartes --- .../migrations/0087_auto_20200130_1312.py | 63 +++++++++++++++++++ apps/establishment/models.py | 19 ++++++ apps/establishment/serializers/common.py | 27 ++++---- apps/establishment/transfer_data.py | 16 ++++- apps/transfer/management/commands/transfer.py | 2 + apps/transfer/models.py | 17 +++++ apps/transfer/serializers/establishment.py | 62 +++++++++++++++++- make_data_migration.sh | 1 + 8 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 apps/establishment/migrations/0087_auto_20200130_1312.py diff --git a/apps/establishment/migrations/0087_auto_20200130_1312.py b/apps/establishment/migrations/0087_auto_20200130_1312.py new file mode 100644 index 00000000..c5c67693 --- /dev/null +++ b/apps/establishment/migrations/0087_auto_20200130_1312.py @@ -0,0 +1,63 @@ +# Generated by Django 2.2.7 on 2020-01-30 13:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('establishment', '0086_auto_20200129_1301'), + ] + + operations = [ + migrations.AddField( + model_name='menu', + name='average_desert_price', + field=models.FloatField(blank=True, default=0, verbose_name='average desert price'), + ), + migrations.AddField( + model_name='menu', + name='average_main_dish_price', + field=models.FloatField(blank=True, default=0, verbose_name='average main dish price'), + ), + migrations.AddField( + model_name='menu', + name='average_starter_price', + field=models.FloatField(blank=True, default=0, verbose_name='average starter price'), + ), + migrations.AddField( + model_name='menu', + name='highest_price', + field=models.FloatField(blank=True, null=True, verbose_name='dish highest price'), + ), + migrations.AddField( + model_name='menu', + name='lowest_price', + field=models.FloatField(blank=True, null=True, verbose_name='dish lowest price'), + ), + migrations.AddField( + model_name='menu', + name='nb_wine', + field=models.IntegerField(blank=True, null=True, verbose_name='NB wine'), + ), + migrations.AddField( + model_name='menu', + name='price_max_by_glass', + field=models.FloatField(blank=True, null=True, verbose_name='max price for wine served by glass'), + ), + migrations.AddField( + model_name='menu', + name='price_min_by_glass', + field=models.FloatField(blank=True, null=True, verbose_name='min price for wine served by glass'), + ), + migrations.AddField( + model_name='menu', + name='renewal_per_year', + field=models.IntegerField(blank=True, null=True, verbose_name='renewal per year'), + ), + migrations.AddField( + model_name='menu', + name='served_by_glasses', + field=models.NullBooleanField(verbose_name='is wine served by glass'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 75c5a164..555b26e1 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -1332,6 +1332,25 @@ class Menu(TranslatedFieldsMixin, BaseAttributes): blank=True, null=True, default=None, verbose_name=_('category'), help_text='{"en-GB":"some text"}') + # a la cartes + average_starter_price = models.FloatField(default=0, blank=True, + verbose_name=_('average starter price')) + average_main_dish_price = models.FloatField(default=0, blank=True, + verbose_name=_('average main dish price')) + renewal_per_year = models.IntegerField(null=True, blank=True, + verbose_name=_('renewal per year')) + average_desert_price = models.FloatField(default=0, blank=True, + verbose_name=_('average desert price')) + nb_wine = models.IntegerField(null=True, blank=True, verbose_name=_('NB wine')) + lowest_price = models.FloatField(null=True, blank=True, verbose_name=_('dish lowest price')) + highest_price = models.FloatField(null=True, blank=True, verbose_name=_('dish highest price')) + served_by_glasses = models.NullBooleanField(null=True, + verbose_name=_('is wine served by glass')) + price_min_by_glass = models.FloatField(null=True, blank=True, + verbose_name=_('min price for wine served by glass')) + price_max_by_glass = models.FloatField(null=True, blank=True, + verbose_name=_('max price for wine served by glass')) + old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) objects = MenuQuerySet.as_manager() diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 3af43e27..68c092c6 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -12,7 +12,8 @@ from comment.serializers import common as comment_serializers from establishment import models from location.serializers import ( AddressBaseSerializer, AddressDetailSerializer, CityBaseSerializer, - CityShortSerializer, EstablishmentWineOriginBaseSerializer, EstablishmentWineRegionBaseSerializer, + CityShortSerializer, EstablishmentWineOriginBaseSerializer, + EstablishmentWineRegionBaseSerializer, ) from main.serializers import AwardSerializer, CurrencySerializer from review.serializers import ReviewShortSerializer @@ -142,17 +143,19 @@ class MenuRUDSerializers(ProjectModelSerializer): schedules = ScheduleRUDSerializer(many=True, allow_null=True, required=False) uploads = MenuFilesSerializers(many=True) - class Meta: - model = models.Menu - fields = [ - 'id', - 'name', - 'establishment_id', - 'establishment_slug', - 'price', - 'drinks_included', - 'schedules', - 'uploads', + class Meta(MenuSerializers.Meta): + """Overridden Meta class.""" + fields = MenuSerializers.Meta.fields + [ + 'average_starter_price', + 'average_main_dish_price', + 'average_desert_price', + 'renewal_per_year', + 'nb_wine', + 'lowest_price', + 'highest_price', + 'served_by_glasses', + 'price_min_by_glass', + 'price_max_by_glass', ] diff --git a/apps/establishment/transfer_data.py b/apps/establishment/transfer_data.py index 741a9989..6b521edb 100644 --- a/apps/establishment/transfer_data.py +++ b/apps/establishment/transfer_data.py @@ -6,9 +6,10 @@ from establishment.models import Establishment from location.models import Address from product.models import PurchasedProduct, Product from transfer.models import Establishments, Dishes, EstablishmentNotes, \ - EstablishmentMerchandises + EstablishmentMerchandises, ALaCartes from transfer.serializers.establishment import EstablishmentSerializer, \ - EstablishmentNoteSerializer + EstablishmentNoteSerializer, \ + ALaCartesSerializer from transfer.serializers.plate import PlateSerializer @@ -179,6 +180,16 @@ def transfer_purchased_plaques(): f'Not existed establishment: {not_existed_establishment_counter}') +def transfer_a_la_cartes(): + """Transfer A la Cartes table.""" + queryset = ALaCartes.objects.exclude(establishment_id__isnull=True) + serialized_data = ALaCartesSerializer(data=list(queryset.values()), many=True) + if serialized_data.is_valid(): + serialized_data.save() + else: + pprint(f"A la Cartes serializer errors: {serialized_data.errors}") + + data_types = { "establishment": [ transfer_establishment, @@ -191,4 +202,5 @@ data_types = { "purchased_plaques": [ transfer_purchased_plaques ], + "a_la_cartes": [transfer_a_la_cartes], } diff --git a/apps/transfer/management/commands/transfer.py b/apps/transfer/management/commands/transfer.py index 2f747300..938893f1 100644 --- a/apps/transfer/management/commands/transfer.py +++ b/apps/transfer/management/commands/transfer.py @@ -1,4 +1,5 @@ from django.core.management.base import BaseCommand + from transfer.utils import transfer_objects @@ -58,6 +59,7 @@ class Command(BaseCommand): 'set_unused_regions', 'update_fake_country_flag', 'transfer_text_review', # переводы для review с их авторами - запускать после overlook и product_review + 'a_la_cartes', ] def handle(self, *args, **options): diff --git a/apps/transfer/models.py b/apps/transfer/models.py index 6a9ba3af..17b174eb 100644 --- a/apps/transfer/models.py +++ b/apps/transfer/models.py @@ -1271,3 +1271,20 @@ class Panels(MigrateMixin): class Meta: managed = False db_table = 'panels' + + +class ALaCartes(MigrateMixin): + using = 'legacy' + + establishment = models.ForeignKey(Establishments, on_delete=models.DO_NOTHING, null=True) + renewal_per_year = models.IntegerField(null=True) + nb_wine = models.IntegerField(null=True) + lowest_price = models.FloatField(null=True) + highest_price = models.FloatField(null=True) + by_glass = models.CharField(null=True, max_length=25) + price_min_by_glass = models.FloatField(null=True) + price_max_by_glass = models.FloatField(null=True) + + class Meta: + managed = False + db_table = 'a_la_cartes' diff --git a/apps/transfer/serializers/establishment.py b/apps/transfer/serializers/establishment.py index 638ba4ff..f268bdc9 100644 --- a/apps/transfer/serializers/establishment.py +++ b/apps/transfer/serializers/establishment.py @@ -2,17 +2,17 @@ from django.conf import settings from django.core.exceptions import MultipleObjectsReturned, ValidationError from django.db import transaction from django.utils.text import slugify +from phonenumber_field.phonenumber import PhoneNumber from rest_framework import serializers from account.models import User from establishment.models import Establishment, ContactEmail, ContactPhone, \ - EstablishmentType, EstablishmentSubType, EstablishmentNote + EstablishmentType, EstablishmentSubType, EstablishmentNote, Menu from location.models import Address from timetable.models import Timetable from utils.legacy_parser import parse_legacy_schedule_content from utils.serializers import TimeZoneChoiceField from utils.slug_generator import generate_unique_slug -from phonenumber_field.phonenumber import PhoneNumber class EstablishmentSerializer(serializers.ModelSerializer): @@ -230,3 +230,61 @@ class EstablishmentNoteSerializer(serializers.ModelSerializer): qs = User.objects.exclude(old_id__isnull=True).filter(old_id=old_id) if qs.exists(): return qs.first() + + +class ALaCartesSerializer(serializers.ModelSerializer): + """Serializer for model Menu.""" + establishment_id = serializers.IntegerField() + renewal_per_year = serializers.IntegerField(allow_null=True) + nb_wine = serializers.IntegerField(allow_null=True) + lowest_price = serializers.FloatField(allow_null=True) + highest_price = serializers.FloatField(allow_null=True) + by_glass = serializers.CharField(allow_null=True) + price_min_by_glass = serializers.FloatField(allow_null=True) + price_max_by_glass = serializers.FloatField(allow_null=True) + + class Meta: + model = Menu + fields = ( + 'establishment_id', + 'renewal_per_year', + 'nb_wine', + 'lowest_price', + 'highest_price', + 'by_glass', + 'price_min_by_glass', + 'price_max_by_glass', + ) + + def validate(self, attrs): + return { + 'establishment': self.get_establishment(attrs.pop('establishment_id')), + 'renewal_per_year': attrs.pop('renewal_per_year', None), + 'nb_wine': attrs.pop('nb_wine', None), + 'lowest_price': attrs.pop('lowest_price', None), + 'highest_price': attrs.pop('highest_price', None), + 'served_by_glasses': self.get_served_by_glasses(attrs.pop('by_glass', None)), + 'price_min_by_glass': attrs.pop('price_min_by_glass', None), + 'price_max_by_glass': attrs.pop('price_max_by_glass', None), + } + + def get_establishment(self, old_id): + establishment_qs = Establishment.objects.filter(old_id=old_id) + if establishment_qs.exists(): + return establishment_qs.first() + + def get_served_by_glasses(self, value): + if value: + value = value.lower() + if value == 'true': + return True + elif value == 'false': + return False + + def create(self, validated_data): + menu_qs = Menu.objects.filter(establishment=validated_data.pop('establishment', None)) + if menu_qs.exists(): + menu = menu_qs.first() + for attr_name, attr_value in validated_data.items(): + setattr(menu, attr_name, attr_value) + menu.save() diff --git a/make_data_migration.sh b/make_data_migration.sh index 6de3a713..ee968ff5 100755 --- a/make_data_migration.sh +++ b/make_data_migration.sh @@ -19,6 +19,7 @@ ./manage.py transfer --inquiries ./manage.py transfer --assemblage ./manage.py transfer --purchased_plaques +./manage.py transfer --a_la_cartes ./manage.py rm_empty_images ./manage.py add_artisan_subtype # добавляет подтипы для заведений артизанов