from django.core.exceptions import MultipleObjectsReturned, ValidationError from django.db import transaction from rest_framework import serializers from establishment.models import Establishment, ContactEmail, ContactPhone, EstablishmentType 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 class EstablishmentSerializer(serializers.ModelSerializer): slug = serializers.CharField(allow_null=True, allow_blank=True) type = serializers.CharField() description = serializers.DictField( allow_null=True, child=serializers.CharField(allow_null=True), ) schedules = serializers.CharField(allow_null=True, allow_blank=True) location = serializers.IntegerField(allow_null=True) email = serializers.CharField(allow_null=True, allow_blank=True) phone = serializers.CharField(allow_null=True, allow_blank=True) website = serializers.CharField(allow_null=True, allow_blank=True) facebook = serializers.CharField(allow_null=True, allow_blank=True) twitter = serializers.CharField(allow_null=True, allow_blank=True) booking = serializers.CharField(allow_null=True, allow_blank=True) state = serializers.CharField(allow_null=True) tz = TimeZoneChoiceField() created = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S') class Meta: model = Establishment fields = ( 'created', 'old_id', # + 'name', # + 'name_translated', # + 'tz', # + 'website', # + 'facebook', # + 'twitter', # + 'lafourchette', # + 'booking', # + 'type', # + см в JIRA 'slug', # + сгенерировать уникальный слаг 'description', # + (разобрал в transfer_data) 'schedules', # + разобрать RUBY словать (2 варианта) 'location', # + получить новые объекты Address по old_id 'email', # + создать объект для ContactEmail 'phone', # + создать объект для ContactPhone 'state', # + создать объект для ContactPhone ) def validate(self, data): data.update({ 'slug': generate_unique_slug(Establishment, data['slug'] if data['slug'] else data['name']), 'address_id': self.get_address(data['location']), 'establishment_type_id': self.get_type(data), 'is_publish': data.get('state') == 'published', }) data.pop('location') data.pop('type') data.pop('state') return data @transaction.atomic def create(self, validated_data): email = validated_data.pop('email') phone = validated_data.pop('phone') schedules = validated_data.pop('schedules') establishment = Establishment.objects.create(**validated_data) if email: ContactEmail.objects.get_or_create( email=email, establishment=establishment, ) if phone: ContactPhone.objects.get_or_create( phone=phone, establishment=establishment, ) if schedules: new_schedules = self.get_schedules(schedules) for schedule in new_schedules: establishment.schedule.add(schedule) establishment.save() return establishment @staticmethod def get_address(address): address = Address.objects.filter(old_id=address).first() if address: return address.id return None # return None @staticmethod def get_type(data): types = { 'Restaurant': EstablishmentType.RESTAURANT, 'Shop': EstablishmentType.ARTISAN, } obj, _ = EstablishmentType.objects.get_or_create(index_name=types[data['type']]) return obj.id @staticmethod def get_schedules(schedules): result = [] legacy_dict = parse_legacy_schedule_content(schedules) weekdays = { 'su': Timetable.SUNDAY, 'mo': Timetable.MONDAY, 'tu': Timetable.THURSDAY, 'we': Timetable.WEDNESDAY, 'th': Timetable.THURSDAY, 'fr': Timetable.FRIDAY, 'sa': Timetable.SATURDAY, } for key, val in legacy_dict.items(): payload = { 'weekday': weekdays[key], 'lunch_start': None, 'lunch_end': None, 'dinner_start': None, 'dinner_end': None, 'opening_at': None, 'closed_at': None, } if val.get('morning'): payload.update({ 'lunch_start': val['morning'].get('start'), 'lunch_end': val['morning'].get('end'), }) if val.get('afternoon'): payload.update({ 'dinner_start': val['afternoon'].get('start'), 'dinner_end': val['afternoon'].get('end'), }) try: obj, _ = Timetable.objects.get_or_create(**payload) except ValidationError: obj = None except MultipleObjectsReturned: obj = Timetable.objects.filter(**payload).first() if obj: result.append(obj) return result