establishment fin

This commit is contained in:
alex 2019-10-27 16:23:30 +03:00
parent 16f06ce2f1
commit 25a2edf17d
7 changed files with 282 additions and 41 deletions

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.4 on 2019-10-27 07:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('establishment', '0043_establishment_currency'),
]
operations = [
migrations.AddField(
model_name='establishment',
name='old_id',
field=models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id'),
),
]

View File

@ -14,6 +14,8 @@ from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
from pytz import timezone as ptz
from timezone_field import TimeZoneField
from collection.models import Collection from collection.models import Collection
from location.models import Address from location.models import Address
@ -21,7 +23,6 @@ from main.models import Award, Currency
from review.models import Review from review.models import Review
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin, from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
TranslatedFieldsMixin, BaseAttributes) TranslatedFieldsMixin, BaseAttributes)
from timezone_field import TimeZoneField
# todo: establishment type&subtypes check # todo: establishment type&subtypes check
@ -296,6 +297,7 @@ class EstablishmentQuerySet(models.QuerySet):
class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin): class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
"""Establishment model.""" """Establishment model."""
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
name = models.CharField(_('name'), max_length=255, default='') name = models.CharField(_('name'), max_length=255, default='')
name_translated = models.CharField(_('Transliterated name'), name_translated = models.CharField(_('Transliterated name'),
max_length=255, default='') max_length=255, default='')
@ -436,7 +438,7 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
@property @property
def works_now(self): def works_now(self):
""" Is establishment working now """ """ Is establishment working now """
now_at_est_tz = datetime.now(tz=self.tz) now_at_est_tz = datetime.now(tz=ptz(self.tz))
current_week = now_at_est_tz.weekday() current_week = now_at_est_tz.weekday()
schedule_for_today = self.schedule.filter(weekday=current_week).first() schedule_for_today = self.schedule.filter(weekday=current_week).first()
if schedule_for_today is None or schedule_for_today.closed_at is None or schedule_for_today.opening_at is None: if schedule_for_today is None or schedule_for_today.closed_at is None or schedule_for_today.opening_at is None:

View File

@ -7,15 +7,41 @@ from transfer.serializers.establishment import EstablishmentSerializer
def transfer_establishment(): def transfer_establishment():
result = [] result = []
old_establishments = Establishments.objects.all().prefetch_related('establishmentinfos_set', 'schedules_set') old_establishments = Establishments.objects.exclude(
type='Wineyard',
).prefetch_related(
'establishmentinfos_set',
'schedules_set',
'descriptions_set',
)
for item in old_establishments: for item in old_establishments:
data = { data = {
'old_id': item.id,
'name': item.name, 'name': item.name,
'name_translated': item.index_name,
'slug': item.slug, 'slug': item.slug,
'type': item.type, 'type': item.type,
'location': item.location.id, 'phone': item.phone,
'schedules': [], 'created': item.created_at,
'description': [],
'tz': None,
'website': None,
'facebook': None,
'twitter': None,
'lafourchette': None,
'booking': None,
'schedules': None,
'location': None,
'email': None,
} }
if item.location:
data.update({
'location': item.location.id,
'tz': item.location.timezone,
})
# Инфо
info = item.establishmentinfos_set.first() info = item.establishmentinfos_set.first()
if info: if info:
data.update({ data.update({
@ -24,22 +50,30 @@ def transfer_establishment():
'twitter': info.twitter, 'twitter': info.twitter,
'lafourchette': info.lafourchette, 'lafourchette': info.lafourchette,
'booking': info.booking_url, 'booking': info.booking_url,
'email': info.email,
}) })
for schedule in item.schedules_set.all():
data['schedules'].append({ # Время работы
'raw_timetable': schedule.timetable schedule = item.schedules_set.first()
if schedule:
data.update({
'schedules': schedule.timetable,
}) })
# Описание
descriptions = item.descriptions_set.all()
for description in descriptions:
data['description'].append({
description.locale: description.text,
})
result.append(data) result.append(data)
print('-' * 30) serialized_data = EstablishmentSerializer(data=result, many=True)
print(len(result)) if serialized_data.is_valid():
pprint(result[0]) serialized_data.save()
else:
# serialized_data = EstablishmentSerializer(data=result, many=True) pprint(f"Establishment serializer errors: {serialized_data.errors}")
# if serialized_data.is_valid():
# serialized_data.save()
# else:
# pprint(f"Establishment serializer errors: {serialized_data.errors}")
data_types = { data_types = {

View File

@ -0,0 +1,20 @@
# Generated by Django 2.2.4 on 2019-10-27 07:56
from django.db import migrations
import sorl.thumbnail.fields
import utils.methods
class Migration(migrations.Migration):
dependencies = [
('gallery', '0004_merge_20191025_0906'),
]
operations = [
migrations.AlterField(
model_name='image',
name='image',
field=sorl.thumbnail.fields.ImageField(upload_to=utils.methods.image_path, verbose_name='image file'),
),
]

View File

@ -277,7 +277,6 @@ class Collections(MigrateMixin):
db_table = 'collections' db_table = 'collections'
# class CollectionEvents(MigrateMixin): # class CollectionEvents(MigrateMixin):
# using = 'legacy' # using = 'legacy'
# #
@ -369,6 +368,7 @@ class GuideFilters(MigrateMixin):
managed = False managed = False
db_table = 'guide_filters' db_table = 'guide_filters'
# #
# class GuideSections(MigrateMixin): # class GuideSections(MigrateMixin):
# using = 'legacy' # using = 'legacy'
@ -447,6 +447,20 @@ class Establishments(MigrateMixin):
db_table = 'establishments' db_table = 'establishments'
class Descriptions(MigrateMixin):
using = 'legacy'
establishment = models.ForeignKey('Establishments', models.DO_NOTHING, blank=True, null=True)
locale = models.CharField(max_length=5, blank=True, null=True)
text = models.TextField(blank=True, null=True)
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
class Meta:
managed = False
db_table = 'descriptions'
# class EstablishmentAssets(MigrateMixin): # class EstablishmentAssets(MigrateMixin):
# using = 'legacy' # using = 'legacy'
# #

View File

@ -1,26 +1,149 @@
from django.core.exceptions import MultipleObjectsReturned, ValidationError
from django.db import transaction
from rest_framework import serializers from rest_framework import serializers
from establishment.models import Establishment 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.slug_generator import generate_unique_slug
class EstablishmentSerializer(serializers.ModelSerializer): class EstablishmentSerializer(serializers.ModelSerializer):
slug = serializers.CharField(allow_null=True, allow_blank=True)
type = serializers.CharField()
description = serializers.ListField(
allow_null=True,
child=serializers.DictField(
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)
tz = serializers.CharField(allow_null=True, allow_blank=True)
created = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S')
class Meta: class Meta:
model = Establishment model = Establishment
fields = '__all__' 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
)
def validate(self, data): def validate(self, data):
pass data.update({
# data.update({ 'slug': generate_unique_slug(Establishment, data['slug'] if data['slug'] else data['name']),
# 'state': self.get_state(data), 'address_id': self.get_address(data['location']),
# 'template': self.get_template(data), 'establishment_type_id': self.get_type(data),
# 'title': self.get_title(data), })
# 'description': self.get_description(data), data.pop('location')
# }) data.pop('type')
# data.pop('body') return data
# data.pop('locale')
# return data
@transaction.atomic
def create(self, validated_data): def create(self, validated_data):
pass email = validated_data.pop('email')
# return News.objects.create(**validated_data) 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):
# return Address.objects.filter(old_id=address).first()
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['morning']:
payload.update({
'lunch_start': val['morning']['start'],
'lunch_end': val['morning']['end'],
})
if val['afternoon']:
payload.update({
'dinner_start': val['afternoon']['start'],
'dinner_end': val['afternoon']['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

View File

@ -1,3 +1,5 @@
from pprint import pprint
import yaml import yaml
@ -13,8 +15,36 @@ def parse_legacy_news_content(legacy_content):
def parse_legacy_schedule_content(legacy_content): def parse_legacy_schedule_content(legacy_content):
clear_str = '!ruby/hash:ActiveSupport::HashWithIndifferentAccess' initial = legacy_content
content_dict = yaml.safe_load(legacy_content.replace(clear_str, ''))
result = '' s1 = "!ruby/object:ActionController::Parameters"
# TODO: вернуть валидные данные расписания для новой модели s2 = "!ruby/hash:ActiveSupport::HashWithIndifferentAccess"
for _ in (s1, s2):
legacy_content = legacy_content.replace(_, "")
content_dict = yaml.safe_load(legacy_content)
if s1 not in initial or s2 not in initial:
return yaml.safe_load(legacy_content)
result = {}
for k, v in content_dict.items():
try:
if v["parameters"]["afternoon"]:
afternoon = v["parameters"]["afternoon"]["parameters"]
else:
afternoon = None
if v["parameters"]["morning"]:
morning = v["parameters"]["morning"]["parameters"]
else:
morning = None
data = {"afternoon": afternoon, "morning": morning}
result.update({k: data})
except KeyError:
print('--------' * 7)
pprint(initial)
raise KeyError
return result return result