Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
alex 2019-11-01 10:48:56 +03:00
commit 383032b2af
24 changed files with 537 additions and 79 deletions

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2.4 on 2019-10-25 16:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('booking', '0002_auto_20191003_1601'),
]
operations = [
migrations.AddField(
model_name='booking',
name='amount',
field=models.CharField(default=None, max_length=30, null=True, verbose_name='prepayment price'),
),
migrations.AddField(
model_name='booking',
name='stripe_key',
field=models.TextField(default=None, null=True, verbose_name='stripe service payment key'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.4 on 2019-10-25 16:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('booking', '0003_auto_20191025_1613'),
]
operations = [
migrations.AddField(
model_name='booking',
name='stripe_token',
field=models.TextField(default=None, null=True, verbose_name='stripe service pre-payed booking token'),
),
]

View File

@ -24,6 +24,9 @@ class Booking(ProjectBaseMixin):
pending_booking_id = models.TextField(verbose_name=_('external service pending booking'), default=None) pending_booking_id = models.TextField(verbose_name=_('external service pending booking'), default=None)
booking_id = models.TextField(verbose_name=_('external service booking id'), default=None, null=True, booking_id = models.TextField(verbose_name=_('external service booking id'), default=None, null=True,
db_index=True, ) db_index=True, )
stripe_key = models.TextField(null=True, default=None, verbose_name=_('stripe service payment key'))
stripe_token = models.TextField(null=True, default=None, verbose_name=_('stripe service pre-payed booking token'))
amount = models.CharField(null=True, default=None, verbose_name=_('prepayment price'), max_length=30)
user = models.ForeignKey( user = models.ForeignKey(
'account.User', verbose_name=_('booking owner'), null=True, 'account.User', verbose_name=_('booking owner'), null=True,
related_name='bookings', related_name='bookings',

View File

@ -1,10 +1,13 @@
from abc import ABC, abstractmethod
import json import json
from abc import ABC, abstractmethod
import requests import requests
from django.conf import settings from django.conf import settings
from rest_framework import status from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers, status
from rest_framework.response import Response
import booking.models.models as models import booking.models.models as models
from rest_framework import serializers
class AbstractBookingService(ABC): class AbstractBookingService(ABC):
@ -24,8 +27,12 @@ class AbstractBookingService(ABC):
self.url = settings.LASTABLE_SERVICE self.url = settings.LASTABLE_SERVICE
@staticmethod @staticmethod
def get_certain_keys(d: dict, keys_to_preserve: set) -> dict: def get_certain_keys(d: dict, keys_to_preserve: set, required=True) -> dict:
""" Helper """ """ Helper """
if required:
diff = keys_to_preserve - d.keys()
if diff:
raise serializers.ValidationError({field: _(f'This field is required') for field in diff})
return {key: d[key] for key in d.keys() & keys_to_preserve} return {key: d[key] for key in d.keys() & keys_to_preserve}
@abstractmethod @abstractmethod
@ -66,22 +73,22 @@ class GuestonlineService(AbstractBookingService):
def get_common_headers(self): def get_common_headers(self):
return {'X-Token': self.token, 'Content-type': 'application/json', 'Accept': 'application/json'} return {'X-Token': self.token, 'Content-type': 'application/json', 'Accept': 'application/json'}
def check_whether_booking_available(self, restaurant_id, date: str): def check_whether_booking_available(self, restaurant_id, *args, **kwargs):
super().check_whether_booking_available(restaurant_id, date) url = f'{self.url}v1/periods'
url = f'{self.url}v1/runtime_services' params = {'restaurant_id': restaurant_id, **kwargs}
params = {'restaurant_id': restaurant_id, 'date': date, 'expands[]': 'table_availabilities'}
r = requests.get(url, headers=self.get_common_headers(), params=params) r = requests.get(url, headers=self.get_common_headers(), params=params)
if not status.is_success(r.status_code): if not status.is_success(r.status_code):
return False return False
response = json.loads(r.content)['runtime_services'] self.response = r.json()
keys_to_preserve = {'left_seats', 'table_availabilities', 'closed', 'start_time', 'end_time', 'last_booking'}
response = map(lambda x: self.get_certain_keys(x, keys_to_preserve), response)
self.response = response
return True return True
def commit_booking(self, payload): def commit_booking(self, payload, stripe_token = None):
url = f'{self.url}v1/pending_bookings/{payload}/commit' url = f'{self.url}v1/pending_bookings/{payload}/commit'
r = requests.put(url, headers=self.get_common_headers()) if stripe_token:
r = requests.put(url, headers=self.get_common_headers(),
data=json.dumps({'stripe_token': stripe_token}))
else:
r = requests.put(url, headers=self.get_common_headers())
self.response = json.loads(r.content) self.response = json.loads(r.content)
if status.is_success(r.status_code) and self.response is None: if status.is_success(r.status_code) and self.response is None:
raise serializers.ValidationError(detail='Booking already committed.') raise serializers.ValidationError(detail='Booking already committed.')
@ -93,8 +100,13 @@ class GuestonlineService(AbstractBookingService):
payload['lastname'] = payload.pop('last_name') payload['lastname'] = payload.pop('last_name')
payload['firstname'] = payload.pop('first_name') payload['firstname'] = payload.pop('first_name')
payload['mobile_phone'] = payload.pop('phone') payload['mobile_phone'] = payload.pop('phone')
payload['user_locale'] = payload.pop('country_code')
headers = self.get_common_headers() headers = self.get_common_headers()
r = requests.put(url, headers=headers, data=json.dumps({'contact_info': payload})) r = requests.put(url, headers=headers, data=json.dumps({'contact_info': payload}))
response = r.json()
self.response = response.get('prepayment')
if not status.is_success(r.status_code):
return Response(status=r.status_code, data=response)
return status.is_success(r.status_code) return status.is_success(r.status_code)
def create_booking(self, payload): def create_booking(self, payload):
@ -103,7 +115,10 @@ class GuestonlineService(AbstractBookingService):
payload['persons'] = payload.pop('booked_persons_number') payload['persons'] = payload.pop('booked_persons_number')
payload['date'] = payload.pop('booking_date') payload['date'] = payload.pop('booking_date')
r = requests.post(url, headers=self.get_common_headers(), data=json.dumps(payload)) r = requests.post(url, headers=self.get_common_headers(), data=json.dumps(payload))
return json.loads(r.content)['id'] if status.is_success(r.status_code) else False if status.is_success(r.status_code):
return json.loads(r.content)['id']
else:
return Response(status=r.status_code, data=r.json())
def cancel_booking(self, payload): def cancel_booking(self, payload):
url = f'{self.url}v1/pending_bookings/{payload}' url = f'{self.url}v1/pending_bookings/{payload}'

View File

@ -42,13 +42,29 @@ class PendingBookingSerializer(serializers.ModelSerializer):
'user', 'user',
) )
class CommitBookingSerializer(serializers.ModelSerializer):
class Meta:
model = models.Booking
fields = (
'stripe_token',
)
def update(self, instance, validated_data):
"""Override update method"""
# Update user password from instance
service = instance.get_service_by_type(instance.type)
service.commit_booking(instance.pending_booking_id, validated_data.get('stripe_token'))
instance.stripe_token = validated_data.get('stripe_token')
instance.save()
return instance
class UpdateBookingSerializer(serializers.ModelSerializer): class UpdateBookingSerializer(serializers.ModelSerializer):
id = serializers.ReadOnlyField() id = serializers.ReadOnlyField()
class Meta: class Meta:
model = models.Booking model = models.Booking
fields = ('booking_id', 'id') fields = ('booking_id', 'id', 'stripe_key', 'amount')
class GetBookingSerializer(serializers.ModelSerializer): class GetBookingSerializer(serializers.ModelSerializer):

View File

@ -8,6 +8,7 @@ urlpatterns = [
path('<int:establishment_id>/check/', views.CheckWhetherBookingAvailable.as_view(), name='booking-check'), path('<int:establishment_id>/check/', views.CheckWhetherBookingAvailable.as_view(), name='booking-check'),
path('<int:establishment_id>/create/', views.CreatePendingBooking.as_view(), name='create-pending-booking'), path('<int:establishment_id>/create/', views.CreatePendingBooking.as_view(), name='create-pending-booking'),
path('<int:pk>/', views.UpdatePendingBooking.as_view(), name='update-pending-booking'), path('<int:pk>/', views.UpdatePendingBooking.as_view(), name='update-pending-booking'),
path('<int:pk>/commit/', views.CommitPendingBooking.as_view(), name='update-pending-booking'),
path('<int:pk>/cancel/', views.CancelBooking.as_view(), name='cancel-existing-booking'), path('<int:pk>/cancel/', views.CancelBooking.as_view(), name='cancel-existing-booking'),
path('last/', views.LastBooking.as_view(), name='last_booking-for-authorizer-user'), path('last/', views.LastBooking.as_view(), name='last_booking-for-authorizer-user'),
path('retrieve/<int:pk>/', views.GetBookingById.as_view(), name='retrieves-booking-by-id'), path('retrieve/<int:pk>/', views.GetBookingById.as_view(), name='retrieves-booking-by-id'),

View File

@ -1,11 +1,13 @@
from rest_framework import generics, permissions, status, serializers
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from establishment.models import Establishment from rest_framework import generics, permissions, status, serializers
from booking.models.models import Booking, GuestonlineService, LastableService
from rest_framework.response import Response from rest_framework.response import Response
from booking.serializers.web import (PendingBookingSerializer,
UpdateBookingSerializer, GetBookingSerializer, CheckBookingSerializer) from booking.models.models import Booking, GuestonlineService, LastableService
from booking.serializers.web import (PendingBookingSerializer, UpdateBookingSerializer, GetBookingSerializer,
CheckBookingSerializer, CommitBookingSerializer)
from establishment.models import Establishment
from notification.models import Subscriber
from utils.methods import get_user_ip
class CheckWhetherBookingAvailable(generics.GenericAPIView): class CheckWhetherBookingAvailable(generics.GenericAPIView):
@ -28,7 +30,9 @@ class CheckWhetherBookingAvailable(generics.GenericAPIView):
service = l_service service = l_service
service.service_id = establishment.lastable_id service.service_id = establishment.lastable_id
elif (not establishment.guestonline_id is None) and g_service \ elif (not establishment.guestonline_id is None) and g_service \
.check_whether_booking_available(establishment.guestonline_id, date): .check_whether_booking_available(establishment.guestonline_id,
**g_service.get_certain_keys(request.query_params,
{'date', 'persons'})):
is_booking_available = True is_booking_available = True
service = g_service service = g_service
service.service_id = establishment.guestonline_id service.service_id = establishment.guestonline_id
@ -61,7 +65,9 @@ class CreatePendingBooking(generics.CreateAPIView):
} }
data['pending_booking_id'] = service.create_booking( data['pending_booking_id'] = service.create_booking(
service.get_certain_keys(data.copy(), service_to_keys[data.get('type')])) service.get_certain_keys(data.copy(), service_to_keys[data.get('type')]))
if not data['pending_booking_id']: if isinstance(data['pending_booking_id'], Response):
return data['pending_booking_id']
elif not data['pending_booking_id']:
return Response(status=status.HTTP_403_FORBIDDEN, data='Unable to create booking') return Response(status=status.HTTP_403_FORBIDDEN, data='Unable to create booking')
data['booking_id'] = data['pending_booking_id'] if data.get('type') == Booking.LASTABLE else None data['booking_id'] = data['pending_booking_id'] if data.get('type') == Booking.LASTABLE else None
serializer = self.get_serializer(data=data) serializer = self.get_serializer(data=data)
@ -70,6 +76,13 @@ class CreatePendingBooking(generics.CreateAPIView):
return Response(status=status.HTTP_201_CREATED, data=serializer.data) return Response(status=status.HTTP_201_CREATED, data=serializer.data)
class CommitPendingBooking(generics.UpdateAPIView):
""" Commit pending booking """
queryset = Booking.objects.all()
permission_classes = (permissions.AllowAny,)
serializer_class = CommitBookingSerializer
class UpdatePendingBooking(generics.UpdateAPIView): class UpdatePendingBooking(generics.UpdateAPIView):
""" Update pending booking with contacts """ """ Update pending booking with contacts """
queryset = Booking.objects.all() queryset = Booking.objects.all()
@ -81,9 +94,29 @@ class UpdatePendingBooking(generics.UpdateAPIView):
data = request.data.copy() data = request.data.copy()
service = Booking.get_service_by_type(instance.type) service = Booking.get_service_by_type(instance.type)
data['pending_booking_id'] = instance.pending_booking_id data['pending_booking_id'] = instance.pending_booking_id
service.update_booking(service.get_certain_keys(data, { r = service.update_booking(service.get_certain_keys(data, {
'email', 'phone', 'last_name', 'first_name', 'country_code', 'pending_booking_id', 'email', 'phone', 'last_name', 'first_name', 'country_code', 'pending_booking_id', 'note',
})) }))
if isinstance(r, Response):
return r
if data.get('newsletter'):
Subscriber.objects.make_subscriber(email=data['email'], country_code=data['country_code'],
locale=request.locale, ip_address=get_user_ip(request),
user=request.user)
if service.response:
# если есть предоплата, возвращаем фронту страйп-ключ для совершения оплаты и цену
amount = service.response.get('amount')
stripe_key = service.response.get('stripe_key')
data = {
'id': instance.pk,
'amount': amount,
'stripe_key': stripe_key,
'type': instance.type,
}
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.update(instance, data)
return Response(status=status.HTTP_200_OK, data=data)
service.commit_booking(data['pending_booking_id']) service.commit_booking(data['pending_booking_id'])
data = { data = {
'booking_id': service.response.get('id'), 'booking_id': service.response.get('id'),

View File

View File

@ -0,0 +1,164 @@
from django.core.management.base import BaseCommand
from establishment.models import Establishment
from location.models import Country, Language
from transfer.models import Collections
from collection.models import Collection
from news.models import News
class Command(BaseCommand):
help = 'Import collection'
def handle(self, *args, **kwargs):
raw_qs = Collections.objects.raw('''
select
distinct
a.id,
a.collection_id,
-- a.establishment_id,
a.title,
a.tag_name,
a.slug,
-- a.attachment_file_name,
-- a.attachment_content_type,
-- a.attachment_file_size,
-- a.attachment_suffix_url,
-- active as is_publish,
a.country_code,
-- a.geometries,
a.description,
min(a.start) AS start
from
(
select distinct
c.id,
c.id as collection_id,
m.establishment_id,
c.title, c.tag_name,
c.slug, c.attachment_file_name,
c.attachment_content_type, c.attachment_file_size,
c.attachment_suffix_url,
active,
s.country_code_2 as country_code,
c.geometries,
c.title as description,
m.created_at as start
from collections as c
join metadata m on m.value = c.tag_name
join establishments e on e.id = m.establishment_id
join sites s on s.id = c.site_id
where m.`key` = 'collection'
union
select distinct
c.id,
c.id as collection_id,
m.establishment_id,
c.title, c.tag_name,
c.slug, c.attachment_file_name,
c.attachment_content_type, c.attachment_file_size,
c.attachment_suffix_url,
active,
s.country_code_2 as country_code,
c.geometries,
c.title as description,
m.created_at as start
from collections as c
join metadata m on m.value = c.slug
join establishments e on e.id = m.establishment_id
join sites s on s.id = c.site_id
where m.`key` = 'collection'
) a
group by
a.id,
a.collection_id,
-- a.establishment_id,
a.title,
a.tag_name,
a.slug,
-- a.attachment_file_name,
-- a.attachment_content_type,
-- a.attachment_file_size,
-- a.attachment_suffix_url,
-- active as is_publish,
a.country_code,
a.description
''')
objects = []
queryset = [vars(query) for query in raw_qs]
for obj in queryset:
# establishment = Establishment.objects.filter(old_id=obj['establishment_id']).first()
lang = Language.objects.filter(locale=obj['country_code'])
country = Country.objects.filter(languages__in=lang).first()
if country:
objects.append(
Collection(name={"en-GB": obj['title']}, collection_type=Collection.ORDINARY,
country=country,
description=obj['description'],
slug=obj['slug'], old_id=obj['collection_id'],
start=obj['start']
)
)
Collection.objects.bulk_create(objects)
raw_qs = Collections.objects.raw('''
select
distinct
a.id,
a.collection_id,
a.establishment_id
from
(
select distinct
c.id,
c.id as collection_id,
m.establishment_id,
c.title, c.tag_name,
c.slug, c.attachment_file_name,
c.attachment_content_type, c.attachment_file_size,
c.attachment_suffix_url,
active,
s.country_code_2 as country_code,
c.geometries,
c.title as description,
m.created_at as start
from collections as c
join metadata m on m.value = c.tag_name
join establishments e on e.id = m.establishment_id
join sites s on s.id = c.site_id
where m.`key` = 'collection'
union
select distinct
c.id,
c.id as collection_id,
m.establishment_id,
c.title, c.tag_name,
c.slug, c.attachment_file_name,
c.attachment_content_type, c.attachment_file_size,
c.attachment_suffix_url,
active,
s.country_code_2 as country_code,
c.geometries,
c.title as description,
m.created_at as start
from collections as c
join metadata m on m.value = c.slug
join establishments e on e.id = m.establishment_id
join sites s on s.id = c.site_id
where m.`key` = 'collection'
) a
''')
queryset = [vars(query) for query in raw_qs]
for obj in queryset:
print('COLLECT_ID: {}'.format(obj['collection_id']))
est = Establishment.objects.filter(old_id=obj['establishment_id'])
if est.exists():
inst = est.first()
collect = Collection.objects.filter(old_id=obj['collection_id'])
for c in collect:
inst.collections.add(c)
inst.save()

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.4 on 2019-10-31 13:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('collection', '0016_auto_20191024_1334'),
]
operations = [
migrations.AddField(
model_name='collection',
name='old_id',
field=models.IntegerField(blank=True, null=True),
),
]

View File

@ -76,6 +76,7 @@ class Collection(ProjectBaseMixin, CollectionDateMixin,
slug = models.SlugField(max_length=50, unique=True, slug = models.SlugField(max_length=50, unique=True,
verbose_name=_('Collection slug'), editable=True, null=True) verbose_name=_('Collection slug'), editable=True, null=True)
old_id=models.IntegerField(null=True, blank=True)
objects = CollectionQuerySet.as_manager() objects = CollectionQuerySet.as_manager()
class Meta: class Meta:

View File

@ -27,22 +27,7 @@ card = {
# "country": "Country", # "country": "Country",
} }
}, },
"Guide": {
# как работать с ForeignKey на самого себя(self), поле "parent"
"data_type": "objects",
"dependencies": ("Collection", "self"),
"fields": {
"Guides": {
# нету аналогов для полей start и end
"name": "title"
}
},
"relations": {
# аналалог для поля "collection" не найдено
# "parent": "Guide",
# "collection": "Collection"
}
}
} }
used_apps = ("location", ) used_apps = ("location", )

View File

@ -15,6 +15,13 @@ class Country(TranslatedFieldsMixin, SVGImageMixin, ProjectBaseMixin):
STR_FIELD_NAME = 'name' STR_FIELD_NAME = 'name'
TWENTEEN_HOURS_FORMAT_COUNTRIES = [
'ca', # Canada
'au', # Australia
'us', # USA
'nz', # New Zeland
]
name = TJSONField(null=True, blank=True, default=None, name = TJSONField(null=True, blank=True, default=None,
verbose_name=_('Name'), help_text='{"en-GB":"some text"}') verbose_name=_('Name'), help_text='{"en-GB":"some text"}')
code = models.CharField(max_length=255, unique=True, verbose_name=_('Code')) code = models.CharField(max_length=255, unique=True, verbose_name=_('Code'))
@ -23,6 +30,10 @@ class Country(TranslatedFieldsMixin, SVGImageMixin, ProjectBaseMixin):
languages = models.ManyToManyField(Language, verbose_name=_('Languages')) languages = models.ManyToManyField(Language, verbose_name=_('Languages'))
old_id = models.IntegerField(null=True, blank=True, default=None) old_id = models.IntegerField(null=True, blank=True, default=None)
@property
def time_format(self):
return 'hh:mmA' if self.code.lower() in self.TWENTEEN_HOURS_FORMAT_COUNTRIES else 'hh:mm'
@property @property
def country_id(self): def country_id(self):
return self.id return self.id

View File

@ -8,11 +8,13 @@ from pprint import pprint
def transfer_countries(): def transfer_countries():
queryset = Cities.objects.raw("""SELECT cities.id, cities.country_code_2 queryset = Cities.objects.raw("""
FROM cities WHERE SELECT cities.id, cities.country_code_2
country_code_2 IS NOT NULL AND FROM cities
country_code_2 != "" WHERE country_code_2 IS NOT NULL AND
GROUP BY cities.country_code_2""") country_code_2 != ""
GROUP BY cities.id, cities.country_code_2
""")
queryset = [vars(query) for query in queryset] queryset = [vars(query) for query in queryset]
@ -24,16 +26,24 @@ def transfer_countries():
def transfer_regions(): def transfer_regions():
regions_without_subregion_queryset = Cities.objects.raw("""SELECT cities.id, cities.region_code, regions_without_subregion_queryset = Cities.objects.raw("""
cities.country_code_2, cities.subregion_code SELECT cities.id,
FROM cities WHERE cities.region_code,
(subregion_code IS NULL OR cities.country_code_2,
subregion_code = "") AND cities.subregion_code
region_code IS NOT NULL AND FROM cities
region_code != "" AND WHERE (subregion_code IS NULL
country_code_2 IS NOT NULL AND OR subregion_code = ""
country_code_2 != "" )
GROUP BY region_code""") AND region_code IS NOT NULL
AND region_code != ""
AND country_code_2 IS NOT NULL
AND country_code_2 != ""
GROUP BY cities.id,
cities.region_code,
cities.country_code_2,
cities.subregion_code
""")
regions_without_subregion_queryset = [vars(query) for query in regions_without_subregion_queryset] regions_without_subregion_queryset = [vars(query) for query in regions_without_subregion_queryset]
@ -43,25 +53,34 @@ def transfer_regions():
else: else:
pprint(f"Parent regions serializer errors: {serialized_without_subregion.errors}") pprint(f"Parent regions serializer errors: {serialized_without_subregion.errors}")
regions_with_subregion_queryset = Cities.objects.raw("""SELECT cities.id, cities.region_code, regions_with_subregion_queryset = Cities.objects.raw("""
cities.country_code_2, cities.subregion_code SELECT
FROM cities WHERE cities.id,
subregion_code IS NOT NULL AND cities.region_code,
subregion_code != "" AND cities.country_code_2,
region_code IS NOT NULL AND cities.subregion_code
region_code != "" AND FROM cities
country_code_2 IS NOT NULL AND WHERE subregion_code IS NOT NULL AND
country_code_2 != "" subregion_code != "" AND
AND cities.subregion_code in ( region_code IS NOT NULL AND
SELECT region_code FROM cities WHERE region_code != "" AND
(subregion_code IS NULL OR country_code_2 IS NOT NULL AND
subregion_code = "") AND country_code_2 != ""
region_code IS NOT NULL AND AND cities.subregion_code in
region_code != "" AND (
country_code_2 IS NOT NULL AND SELECT region_code FROM cities WHERE
country_code_2 != "" (subregion_code IS NULL OR
) subregion_code = "") AND
GROUP BY region_code""") region_code IS NOT NULL AND
region_code != "" AND
country_code_2 IS NOT NULL AND
country_code_2 != ""
)
GROUP BY cities.id,
cities.region_code,
cities.country_code_2,
cities.subregion_code
""")
regions_with_subregion_queryset = [vars(query) for query in regions_with_subregion_queryset] regions_with_subregion_queryset = [vars(query) for query in regions_with_subregion_queryset]

View File

@ -64,6 +64,7 @@ class SiteSettingsSerializer(serializers.ModelSerializer):
country_code = serializers.CharField(source='subdomain', read_only=True) country_code = serializers.CharField(source='subdomain', read_only=True)
country_name = serializers.CharField(source='country.name_translated', read_only=True) country_name = serializers.CharField(source='country.name_translated', read_only=True)
time_format = serializers.CharField(source='country.time_format', read_only=True)
class Meta: class Meta:
"""Meta class.""" """Meta class."""
@ -71,6 +72,7 @@ class SiteSettingsSerializer(serializers.ModelSerializer):
model = models.SiteSettings model = models.SiteSettings
fields = ( fields = (
'country_code', 'country_code',
'time_format',
'subdomain', 'subdomain',
'pinterest_page_url', 'pinterest_page_url',
'twitter_page_url', 'twitter_page_url',
@ -81,7 +83,7 @@ class SiteSettingsSerializer(serializers.ModelSerializer):
'ad_config', 'ad_config',
'published_features', 'published_features',
'currency', 'currency',
'country_name' 'country_name',
) )

View File

@ -0,0 +1,29 @@
# Generated by Django 2.2.4 on 2019-10-30 13:15
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('product', '0002_product_slug'),
]
operations = [
migrations.AddField(
model_name='product',
name='old_id',
field=models.IntegerField(blank=True, null=True, verbose_name='Product old id'),
),
migrations.AddField(
model_name='product',
name='old_id_establishment',
field=models.IntegerField(blank=True, null=True, verbose_name='Establishment old id'),
),
migrations.AlterField(
model_name='product',
name='establishment',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='establishment.Establishment', verbose_name='establishment'),
),
]

View File

@ -0,0 +1,33 @@
# Generated by Django 2.2.4 on 2019-10-31 09:23
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('product', '0003_auto_20191030_1315'),
]
operations = [
migrations.RemoveField(
model_name='product',
name='old_id_establishment',
),
migrations.AlterField(
model_name='product',
name='establishment',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='products', to='establishment.Establishment', verbose_name='establishment'),
),
migrations.AlterField(
model_name='product',
name='old_id',
field=models.IntegerField(blank=True, null=True),
),
migrations.AlterField(
model_name='productsubtype',
name='index_name',
field=models.CharField(choices=[('rum', 'Rum'), ('other', 'Other'), ('extra brut', 'extra brut'), ('brut', 'brut'), ('brut nature', 'brut nature'), ('demi-sec', 'demi-sec'), ('Extra Dry', 'Extra Dry'), ('dosage zero', 'dosage zero'), ('sec', 'sec'), ('doux', 'doux'), ('moelleux', 'moelleux')], db_index=True, max_length=50, unique=True, verbose_name='Index name'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.4 on 2019-10-31 09:29
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('product', '0004_auto_20191031_0923'),
]
operations = [
migrations.AlterField(
model_name='product',
name='characteristics',
field=django.contrib.postgres.fields.jsonb.JSONField(null=True, verbose_name='Characteristics'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.4 on 2019-10-31 09:30
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('product', '0005_auto_20191031_0929'),
]
operations = [
migrations.AlterField(
model_name='product',
name='establishment',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='establishment.Establishment', verbose_name='establishment'),
),
]

View File

@ -0,0 +1,29 @@
# Generated by Django 2.2.4 on 2019-10-31 14:08
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('product', '0006_auto_20191031_0930'),
]
operations = [
migrations.RemoveField(
model_name='product',
name='old_id',
),
migrations.AlterField(
model_name='product',
name='characteristics',
field=django.contrib.postgres.fields.jsonb.JSONField(verbose_name='Characteristics', null=True),
),
migrations.AlterField(
model_name='product',
name='establishment',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='products', to='establishment.Establishment', verbose_name='establishment'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.4 on 2019-10-31 14:10
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('product', '0007_auto_20191031_1408'),
]
operations = [
migrations.AlterField(
model_name='product',
name='characteristics',
field=django.contrib.postgres.fields.jsonb.JSONField(null=True, verbose_name='Characteristics'),
),
]

View File

@ -138,7 +138,8 @@ class Product(TranslatedFieldsMixin, BaseAttributes):
help_text='{"en-GB":"some text"}') help_text='{"en-GB":"some text"}')
description = TJSONField(_('Description'), null=True, blank=True, description = TJSONField(_('Description'), null=True, blank=True,
default=None, help_text='{"en-GB":"some text"}') default=None, help_text='{"en-GB":"some text"}')
characteristics = JSONField(_('Characteristics')) #TODO set null=False
characteristics = JSONField(_('Characteristics'), null=True)
country = models.ManyToManyField('location.Country', country = models.ManyToManyField('location.Country',
verbose_name=_('Country')) verbose_name=_('Country'))
available = models.BooleanField(_('Available'), default=True) available = models.BooleanField(_('Available'), default=True)

View File

@ -71,7 +71,7 @@ class RegionSerializer(serializers.ModelSerializer):
print(data) print(data)
if "subregion_code" in data and data["subregion_code"] is not None and data["subregion_code"].strip() != "": if "subregion_code" in data and data["subregion_code"] is not None and data["subregion_code"].strip() != "":
try: try:
parent_region = Region.objects.get(code=str(data['region_code'])) parent_region = Region.objects.filter(code=str(data['region_code'])).first()
except Exception as e: except Exception as e:
raise ValueError(f"Parent region error with {data}: {e}") raise ValueError(f"Parent region error with {data}: {e}")