need checks

This commit is contained in:
Anatoly 2019-11-08 19:46:16 +03:00
parent 9bdeabe352
commit 0f2d1ca071
5 changed files with 428 additions and 159 deletions

View File

@ -4,6 +4,7 @@ from django.contrib.gis.db import models as gis_models
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.core.validators import MaxValueValidator, MinValueValidator
from utils.models import (BaseAttributes, ProjectBaseMixin, from utils.models import (BaseAttributes, ProjectBaseMixin,
TranslatedFieldsMixin, TJSONField) TranslatedFieldsMixin, TJSONField)
@ -18,11 +19,15 @@ class ProductType(TranslatedFieldsMixin, ProjectBaseMixin):
FOOD = 'food' FOOD = 'food'
WINE = 'wine' WINE = 'wine'
LIQUOR = 'liquor' LIQUOR = 'liquor'
SOUVENIR = 'souvenir'
BOOK = 'book'
INDEX_NAME_TYPES = ( INDEX_NAME_TYPES = (
(FOOD, _('Food')), (FOOD, _('Food')),
(WINE, _('Wine')), (WINE, _('Wine')),
(LIQUOR, _('Liquor')), (LIQUOR, _('Liquor')),
(SOUVENIR, _('Souvenir')),
(BOOK, _('Book')),
) )
name = TJSONField(blank=True, null=True, default=None, name = TJSONField(blank=True, null=True, default=None,
@ -49,29 +54,13 @@ class ProductSubType(TranslatedFieldsMixin, ProjectBaseMixin):
# INDEX NAME CHOICES # INDEX NAME CHOICES
RUM = 'rum' RUM = 'rum'
PLATE = 'plate'
OTHER = 'other' 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'
INDEX_NAME_TYPES = ( INDEX_NAME_TYPES = (
(RUM, _('Rum')), (RUM, _('Rum')),
(PLATE, _('Plate')),
(OTHER, _('Other')), (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'))
) )
product_type = models.ForeignKey(ProductType, on_delete=models.CASCADE, product_type = models.ForeignKey(ProductType, on_delete=models.CASCADE,
@ -188,11 +177,15 @@ class Product(TranslatedFieldsMixin, BaseAttributes):
verbose_name=_('public mark'),) verbose_name=_('public mark'),)
wine_region = models.ForeignKey('location.WineRegion', on_delete=models.PROTECT, wine_region = models.ForeignKey('location.WineRegion', on_delete=models.PROTECT,
related_name='wines', related_name='wines',
blank=True, null=True, blank=True, null=True, default=None,
verbose_name=_('wine region')) verbose_name=_('wine region'))
wine_standard = models.ForeignKey('product.WineStandard', on_delete=models.PROTECT, wine_sub_region = models.ForeignKey('location.WineSubRegion', on_delete=models.PROTECT,
blank=True, null=True, related_name='wines',
verbose_name=_('wine standard')) blank=True, null=True, default=None,
verbose_name=_('wine sub region'))
classifications = models.ManyToManyField('product.ProductClassification',
blank=True,
verbose_name=_('classifications'))
wine_village = models.ForeignKey('location.WineVillage', on_delete=models.PROTECT, wine_village = models.ForeignKey('location.WineVillage', on_delete=models.PROTECT,
blank=True, null=True, blank=True, null=True,
verbose_name=_('wine appellation')) verbose_name=_('wine appellation'))
@ -209,6 +202,13 @@ class Product(TranslatedFieldsMixin, BaseAttributes):
verbose_name=_('brand')) verbose_name=_('brand'))
tags = models.ManyToManyField('tag.Tag', related_name='products', tags = models.ManyToManyField('tag.Tag', related_name='products',
verbose_name=_('Tag')) verbose_name=_('Tag'))
old_unique_key = models.CharField(max_length=255, unique=True,
blank=True, null=True, default=None,
help_text=_('attribute from legacy db'))
vintage = models.IntegerField(verbose_name=_('vintage year'),
null=True, blank=True, default=None,
validators=[MinValueValidator(1900),
MaxValueValidator(2100)])
objects = ProductManager.from_queryset(ProductQuerySet)() objects = ProductManager.from_queryset(ProductQuerySet)()
@ -271,33 +271,31 @@ class Unit(models.Model):
return self.name return self.name
class WineStandardQuerySet(models.QuerySet): class ProductStandardQuerySet(models.QuerySet):
"""Wine appellation queryset.""" """Product standard queryset."""
class WineStandard(models.Model): class ProductStandard(models.Model):
"""Wine standard model.""" """Product standard model."""
APPELLATION = 'Appellation' APPELLATION = 0
CLASSIFICATION = 'Classification' WINEQUALITY = 1
WINEQUALITY = 'WineQuality' YARDCLASSIFICATION = 2
YARDCLASSIFICATION = 'YardClassification'
STANDARDS = ( STANDARDS = (
(APPELLATION, _('Appellation')), (APPELLATION, _('Appellation')),
(CLASSIFICATION, _('Classification')),
(WINEQUALITY, _('Wine quality')), (WINEQUALITY, _('Wine quality')),
(YARDCLASSIFICATION, _('Yard classification')), (YARDCLASSIFICATION, _('Yard classification')),
) )
name = models.CharField(_('name'), max_length=255) name = models.CharField(_('name'), max_length=255)
standard_type = models.CharField(max_length=30, choices=STANDARDS, standard_type = models.PositiveSmallIntegerField(choices=STANDARDS,
verbose_name=_('standard type')) verbose_name=_('standard type'))
coordinates = gis_models.PointField( coordinates = gis_models.PointField(
_('Coordinates'), blank=True, null=True, default=None) _('Coordinates'), blank=True, null=True, default=None)
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
objects = WineStandardQuerySet.as_manager() objects = ProductStandardQuerySet.as_manager()
class Meta: class Meta:
"""Meta class.""" """Meta class."""
@ -305,25 +303,49 @@ class WineStandard(models.Model):
verbose_name = _('wine standard') verbose_name = _('wine standard')
class WineClassificationQuerySet(models.QuerySet): class ProductClassificationType(models.Model):
"""Wine classification QuerySet.""" """Product classification type."""
name = models.CharField(max_length=255, unique=True,
class WineClassification(models.Model): verbose_name=_('classification type'))
"""Wine classification model.""" product_type = models.ForeignKey(ProductType, on_delete=models.PROTECT,
name = models.CharField(_('name'), max_length=255) null=True, default=None,
standard = models.ForeignKey(WineStandard, on_delete=models.PROTECT, verbose_name=_('product type'))
verbose_name=_('standard')) product_sub_type = models.ForeignKey(ProductSubType, on_delete=models.PROTECT,
tags = models.ManyToManyField('tag.Tag', related_name='wine_classifications',
verbose_name=_('Tag'))
possible_subtype = models.ForeignKey(ProductSubType, on_delete=models.PROTECT,
blank=True, null=True, default=None, blank=True, null=True, default=None,
help_text=_('Legacy attribute - possible_type')) verbose_name=_('product subtype'),
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) help_text=_('Legacy attribute - possible_type (product type).'
'Product type in our case is product subtype.'))
objects = WineClassificationQuerySet.as_manager()
class Meta: class Meta:
"""Meta class.""" """Meta class."""
verbose_name = _('wine classification') verbose_name = _('wine classification type')
verbose_name_plural = _('wine classifications') verbose_name_plural = _('wine classification types')
def __str__(self):
"""Override str dunder."""
return self.name
class ProductClassificationQuerySet(models.QuerySet):
"""Product classification QuerySet."""
class ProductClassification(models.Model):
"""Product classification model."""
classification_type = models.ForeignKey(ProductClassificationType, on_delete=models.PROTECT,
verbose_name=_('classification type'))
standard = models.ForeignKey(ProductStandard, on_delete=models.PROTECT,
null=True, blank=True, default=None,
verbose_name=_('standard'))
tags = models.ManyToManyField('tag.Tag', related_name='product_classifications',
verbose_name=_('Tag'))
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
objects = ProductClassificationQuerySet.as_manager()
class Meta:
"""Meta class."""
verbose_name = _('product classification')
verbose_name_plural = _('product classifications')

View File

@ -1,10 +1,47 @@
from pprint import pprint from pprint import pprint
from django.conf import settings from django.conf import settings
from tag.models import TagCategory
from transfer import models as transfer_models from transfer import models as transfer_models
from transfer.serializers.partner import PartnerSerializer
from transfer.serializers import product as product_serializers from transfer.serializers import product as product_serializers
from transfer.serializers.partner import PartnerSerializer
from product.models import ProductType, ProductSubType
def transfer_product_types():
product_types = ['wine', 'souvenir']
for product_type in product_types:
ProductType.objects.get_or_create(**{
'name': {settings.FALLBACK_LOCALE: product_type},
'index_name': product_type
})
def transfer_product_subtype():
error_counter = 0
create_counter = 0
product_subtypes = {
'plate': {
'product_type_index_name': 'souvenir',
'name': 'plate',
'index_name': 'plate',
}
}
for product_subtype in product_subtypes.values():
product_type_qs = ProductType.objects.filter(
index_name=product_subtype.get('product_type_index_name'))
if product_type_qs:
product_type = product_type_qs.first()
subtype, status = ProductSubType.objects.get_or_create(**{
'name': {settings.FALLBACK_LOCALE: product_subtype.get('name')},
'index_name': product_subtype.get('index_name'),
'product_type': product_type
})
create_counter += 1 if status else 0
else:
error_counter += 1
print(f'Errors occurred: {error_counter}\nCreated: {create_counter}')
def transfer_partner(): def transfer_partner():
@ -18,16 +55,6 @@ def transfer_partner():
def transfer_wine_color(): def transfer_wine_color():
wine_color_index_name = 'wine_color'
TagCategory.objects.get_or_create(
index_name=wine_color_index_name,
defaults={
'label': {settings.FALLBACK_LOCALE: wine_color_index_name},
'value_type': TagCategory.STRING,
'index_name': wine_color_index_name,
'public': True
})
queryset = transfer_models.WineColor.objects.all() queryset = transfer_models.WineColor.objects.all()
serialized_data = product_serializers.WineColorSerializer( serialized_data = product_serializers.WineColorSerializer(
data=list(queryset.values()), data=list(queryset.values()),
@ -35,20 +62,21 @@ def transfer_wine_color():
if serialized_data.is_valid(): if serialized_data.is_valid():
serialized_data.save() serialized_data.save()
else: else:
pprint(f"WineColorSerializer errors: {serialized_data.errors}") pprint(f"transfer_wine_color errors: {serialized_data.errors}")
def transfer_wine_sugar_content():
queryset = transfer_models.WineType.objects.all()
serialized_data = product_serializers.WineTypeSerializer(
data=list(queryset.values()),
many=True)
if serialized_data.is_valid():
serialized_data.save()
else:
pprint(f"transfer_wine_sugar_content errors: {serialized_data.errors}")
def transfer_wine_bottles_produced(): def transfer_wine_bottles_produced():
bottles_produced_index_name = 'bottles_produced'
TagCategory.objects.get_or_create(
index_name=bottles_produced_index_name,
defaults={
'label': {settings.FALLBACK_LOCALE: bottles_produced_index_name},
'value_type': TagCategory.STRING,
'index_name': bottles_produced_index_name,
'public': True
})
raw_queryset = transfer_models.Products.objects.raw( raw_queryset = transfer_models.Products.objects.raw(
""" """
SELECT SELECT
@ -60,7 +88,7 @@ def transfer_wine_bottles_produced():
""" """
) )
queryset = [vars(query) for query in raw_queryset] queryset = [vars(query) for query in raw_queryset]
serialized_data = product_serializers.BottlesProducedSerializer( serialized_data = product_serializers.WineBottlesProducedSerializer(
data=queryset, data=queryset,
many=True) many=True)
if serialized_data.is_valid(): if serialized_data.is_valid():
@ -69,9 +97,29 @@ def transfer_wine_bottles_produced():
pprint(f"transfer_wine_bottles_produced errors: {serialized_data.errors}") pprint(f"transfer_wine_bottles_produced errors: {serialized_data.errors}")
def transfer_wine_classification_type():
raw_queryset = transfer_models.ProductClassification.objects.raw(
"""
SELECT
DISTINCT name,
1 as id
FROM wine_classifications;
"""
)
queryset = [vars(query) for query in raw_queryset]
serialized_data = product_serializers.WineClassificationTypeSerializer(
data=queryset,
many=True)
if serialized_data.is_valid():
serialized_data.save()
else:
pprint(f"transfer_classification errors: {serialized_data.errors}")
def transfer_wine_standard(): def transfer_wine_standard():
queryset = transfer_models.WineClassification.objects.filter(parent_id__isnull=True) queryset = transfer_models.ProductClassification.objects.filter(parent_id__isnull=True) \
serialized_data = product_serializers.WineStandardSerializer( .exclude(type='Classification')
serialized_data = product_serializers.ProductStandardSerializer(
data=list(queryset.values()), data=list(queryset.values()),
many=True) many=True)
if serialized_data.is_valid(): if serialized_data.is_valid():
@ -81,8 +129,8 @@ def transfer_wine_standard():
def transfer_wine_classifications(): def transfer_wine_classifications():
queryset = transfer_models.WineClassification.objects.filter(parent_id__isnull=False) queryset = transfer_models.ProductClassification.objects.filter(type='Classification')
serialized_data = product_serializers.WineStandardClassificationSerializer( serialized_data = product_serializers.ProductClassificationSerializer(
data=list(queryset.values()), data=list(queryset.values()),
many=True) many=True)
if serialized_data.is_valid(): if serialized_data.is_valid():
@ -125,11 +173,18 @@ def transfer_product():
data_types = { data_types = {
"partner": [transfer_partner], "partner": [transfer_partner],
"product_type": [
transfer_product_types,
transfer_product_subtype,
],
"wine_characteristics": [ "wine_characteristics": [
transfer_wine_sugar_content,
transfer_wine_color, transfer_wine_color,
transfer_wine_bottles_produced, transfer_wine_bottles_produced,
transfer_wine_classification_type,
transfer_wine_standard, transfer_wine_standard,
transfer_wine_classifications], transfer_wine_classifications,
],
"product": [ "product": [
transfer_product_brand, transfer_product_brand,
transfer_product transfer_product

View File

@ -1,6 +1,9 @@
from django.db import models from django.db import models
from django.forms.models import model_to_dict from django.forms.models import model_to_dict
from rest_framework import serializers from rest_framework import serializers
from tag import models as tag_models
from django.conf import settings
from product.models import ProductType
class SecondDbManager(models.Manager): class SecondDbManager(models.Manager):
@ -34,3 +37,16 @@ class TransferSerializerMixin(serializers.ModelSerializer):
qs = self.Meta.model.objects.filter(**validated_data) qs = self.Meta.model.objects.filter(**validated_data)
if not qs.exists(): if not qs.exists():
return super().create(validated_data) return super().create(validated_data)
@property
def tag_category(self):
if self.CATEGORY_LABEL and self.CATEGORY_INDEX_NAME:
tag_category, _ = tag_models.TagCategory.objects.get_or_create(
index_name=self.CATEGORY_INDEX_NAME,
defaults={
'label': {settings.FALLBACK_LOCALE: self.CATEGORY_LABEL},
'value_type': tag_models.TagCategory.STRING,
'index_name': self.CATEGORY_INDEX_NAME,
'public': True
})
return tag_category

View File

@ -919,7 +919,7 @@ class WineType(MigrateMixin):
db_table = 'wine_types' db_table = 'wine_types'
class WineClassification(MigrateMixin): class ProductClassification(MigrateMixin):
using = 'legacy' using = 'legacy'
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
@ -948,20 +948,21 @@ class Products(MigrateMixin):
price = models.FloatField(null=True) price = models.FloatField(null=True)
average_price_in_shops = models.FloatField(null=True) average_price_in_shops = models.FloatField(null=True)
wine_sub_region_id = models.IntegerField(null=True) wine_sub_region_id = models.IntegerField(null=True)
classification = models.ForeignKey('WineClassification', models.DO_NOTHING, null=True, classification = models.ForeignKey('ProductClassification', models.DO_NOTHING, null=True,
related_name='product_classification') related_name='product_classification')
wine_region = models.ForeignKey('WineLocations', models.DO_NOTHING, null=True) wine_region = models.ForeignKey('WineLocations', models.DO_NOTHING, null=True)
wine_type = models.ForeignKey('WineType', models.DO_NOTHING, null=True) wine_type = models.ForeignKey('WineType', models.DO_NOTHING, null=True)
wine_color = models.ForeignKey('WineColor', models.DO_NOTHING, null=True) wine_color = models.ForeignKey('WineColor', models.DO_NOTHING, null=True)
appellation = models.ForeignKey('WineClassification', models.DO_NOTHING, null=True) appellation = models.ForeignKey('ProductClassification', models.DO_NOTHING, null=True)
state = models.CharField(max_length=255) state = models.CharField(max_length=255)
village = models.ForeignKey('WineLocations', models.DO_NOTHING, null=True, village = models.ForeignKey('WineLocations', models.DO_NOTHING, null=True,
related_name='product_village') related_name='product_village')
vineyard = models.ForeignKey('WineLocations', models.DO_NOTHING, null=True, vineyard = models.ForeignKey('WineLocations', models.DO_NOTHING, null=True,
related_name='product_vineyard') related_name='product_vineyard')
wine_quality = models.ForeignKey('WineClassification', models.DO_NOTHING, null=True, wine_quality = models.ForeignKey('ProductClassification', models.DO_NOTHING, null=True,
related_name='product_wine_quality') related_name='product_wine_quality')
bottles_produced = models.CharField(max_length=3000, null=True) bottles_produced = models.CharField(max_length=3000, null=True)
unique_key = models.CharField(max_length=255, null=True)
class Meta: class Meta:
managed = False managed = False

View File

@ -9,10 +9,12 @@ from transfer import models as transfer_models
from utils.methods import get_point_from_coordinates from utils.methods import get_point_from_coordinates
from transfer.mixins import TransferSerializerMixin from transfer.mixins import TransferSerializerMixin
from django.conf import settings from django.conf import settings
from functools import reduce
class WineColorSerializer(TransferSerializerMixin): class WineColorSerializer(TransferSerializerMixin):
TAG_CATEGORY = 'wine_color' CATEGORY_LABEL = 'Wine color'
CATEGORY_INDEX_NAME = slugify(CATEGORY_LABEL)
id = serializers.IntegerField() id = serializers.IntegerField()
name = serializers.CharField(allow_null=True) name = serializers.CharField(allow_null=True)
@ -35,17 +37,35 @@ class WineColorSerializer(TransferSerializerMixin):
attrs['category'] = self.tag_category attrs['category'] = self.tag_category
return attrs return attrs
@property
def tag_category(self): class WineTypeSerializer(TransferSerializerMixin):
qs = tag_models.TagCategory.objects.filter(index_name=self.TAG_CATEGORY) CATEGORY_LABEL = 'Sugar content'
if qs.exists(): CATEGORY_INDEX_NAME = slugify(CATEGORY_LABEL)
return qs.first()
id = serializers.IntegerField()
name = serializers.CharField()
class Meta:
model = tag_models.Tag
fields = (
'id',
'name',
)
def validate(self, attrs):
value = attrs.pop('name')
attrs['old_id'] = attrs.pop('id', None)
attrs['label'] = {settings.FALLBACK_LOCALE: value}
attrs['value'] = slugify(value)
attrs['category'] = self.tag_category
return attrs
class BottlesProducedSerializer(TransferSerializerMixin): class WineBottlesProducedSerializer(TransferSerializerMixin):
TAG_CATEGORY = 'bottles_produced' CATEGORY_LABEL = 'Bottles produced'
CATEGORY_INDEX_NAME = slugify(CATEGORY_LABEL)
bottles_produced = serializers.IntegerField() bottles_produced = serializers.CharField()
class Meta: class Meta:
model = tag_models.Tag model = tag_models.Tag
@ -55,28 +75,37 @@ class BottlesProducedSerializer(TransferSerializerMixin):
def validate(self, attrs): def validate(self, attrs):
value = attrs.pop('bottles_produced') value = attrs.pop('bottles_produced')
attrs['label'] = {settings.FALLBACK_LOCALE: value} parsed_value = self.parsed_value(value)
attrs['value'] = slugify(value) attrs['label'] = {settings.FALLBACK_LOCALE: parsed_value}
attrs['value'] = slugify(parsed_value)
attrs['category'] = self.tag_category attrs['category'] = self.tag_category
return attrs return attrs
@property def parsed_value(self, value):
def tag_category(self): if value.isdigit():
qs = tag_models.TagCategory.objects.filter(index_name=self.TAG_CATEGORY) return int(value)
if qs.exists():
return qs.first() parted = value.split(' ')
if len(parted) > 1:
values = [int(i) if i.isdigit() else 0 for i in parted]
return reduce(lambda a, b: a + b, values)
lowered = value.lower()
if 'magnum' in lowered:
return 1
return 0
class WineStandardSerializer(TransferSerializerMixin): class ProductStandardSerializer(TransferSerializerMixin):
id = serializers.IntegerField() id = serializers.IntegerField()
name = serializers.CharField() name = serializers.CharField()
type = serializers.ChoiceField(choices=models.WineStandard.STANDARDS, type = serializers.CharField(allow_null=True)
allow_null=True)
longitude = serializers.FloatField(allow_null=True) longitude = serializers.FloatField(allow_null=True)
latitude = serializers.FloatField(allow_null=True) latitude = serializers.FloatField(allow_null=True)
class Meta: class Meta:
model = models.WineStandard model = models.ProductStandard
fields = ( fields = (
'id', 'id',
'name', 'name',
@ -88,23 +117,53 @@ class WineStandardSerializer(TransferSerializerMixin):
def validate(self, attrs): def validate(self, attrs):
latitude = attrs.pop('latitude', None) latitude = attrs.pop('latitude', None)
longitude = attrs.pop('longitude', None) longitude = attrs.pop('longitude', None)
standard_type = attrs.pop('type', None)
attrs['coordinates'] = get_point_from_coordinates(latitude, longitude) attrs['coordinates'] = get_point_from_coordinates(latitude, longitude)
attrs['old_id'] = attrs.get('id') attrs['old_id'] = attrs.get('id')
attrs['standard_type'] = attrs.pop('type', None) attrs['standard_type'] = self.get_standard_type(standard_type)
return attrs return attrs
def get_standard_type(self, type: str):
if type == 'Appellation':
return models.ProductStandard.APPELLATION
elif type == 'YardClassification':
return models.ProductStandard.WINEQUALITY
elif type == 'WineQuality':
return models.ProductStandard.YARDCLASSIFICATION
class WineStandardClassificationSerializer(serializers.ModelSerializer):
class WineClassificationTypeSerializer(TransferSerializerMixin):
name = serializers.CharField()
class Meta:
model = models.ProductClassificationType
fields = (
'name',
)
def validate(self, attrs):
attrs['product_type'] = self.wine_type
return attrs
@property
def wine_type(self):
qs = models.ProductType.objects.filter(index_name=models.ProductType.WINE)
if qs.exists():
return qs.first()
class ProductClassificationSerializer(TransferSerializerMixin):
id = serializers.IntegerField() id = serializers.IntegerField()
name = serializers.CharField() name = serializers.CharField()
possible_type_id = serializers.IntegerField(allow_null=True) possible_type_id = serializers.IntegerField(allow_null=True)
possible_color_id = serializers.IntegerField() possible_color_id = serializers.IntegerField(allow_null=True)
parent_id = serializers.IntegerField() parent_id = serializers.IntegerField(allow_null=True)
class Meta: class Meta:
model = models.WineClassification model = models.ProductClassification
fields = ( fields = (
'id', 'id',
'name', 'name',
@ -114,40 +173,56 @@ class WineStandardClassificationSerializer(serializers.ModelSerializer):
) )
def validate(self, attrs): def validate(self, attrs):
classification_name = attrs.pop('name')
possible_type_id = attrs.pop('possible_type_id', None) possible_type_id = attrs.pop('possible_type_id', None)
possible_color_id = attrs.pop('possible_color_id', None) possible_color_id = attrs.pop('possible_color_id', None)
parent_id = attrs.pop('parent_id', None) parent_id = attrs.pop('parent_id', None)
attrs['old_id'] = attrs.pop('id') attrs['old_id'] = attrs.pop('id')
attrs['possible_subtype'] = self.get_possible_type(possible_type_id) attrs['classification_type'] = self.get_classification_type(classification_name)
attrs['possible_subtype_tag'] = self.get_possible_type_tag(possible_type_id)
attrs['possible_color_tag'] = self.get_possible_color_tag(possible_color_id) attrs['possible_color_tag'] = self.get_possible_color_tag(possible_color_id)
attrs['standard'] = self.get_wine_standard(parent_id) attrs['standard'] = self.get_wine_standard(parent_id)
return attrs return attrs
def create(self, validated_data): def create(self, validated_data):
possible_color_tag = validated_data.pop('possible_color_tag', None) possible_color_tag = validated_data.pop('possible_color_tag', None)
obj = super().create(validated_data) possible_subtype_tag = validated_data.pop('possible_subtype_tag', None)
obj, _ = self.Meta.model.objects.get_or_create(**validated_data)
if possible_color_tag: if possible_color_tag:
obj.tags.add(possible_color_tag) obj.tags.add(possible_color_tag)
if possible_subtype_tag:
obj.tags.add(possible_subtype_tag)
return obj return obj
def get_possible_type(self, possible_type_id): def get_classification_type(self, classification_name):
legacy_qs = transfer_models.WineClassification.objects.filter(id=possible_type_id) qs = models.ProductClassificationType.objects.filter(name__icontains=classification_name)
if legacy_qs.exists(): if qs.exists():
qs = models.ProductSubType.objects.filter(index_name=legacy_qs.first()) return qs.first()
def get_possible_type_tag(self, possible_type_id):
if possible_type_id:
qs = tag_models.Tag.objects.filter(
old_id=possible_type_id,
category__index_name=WineTypeSerializer.CATEGORY_INDEX_NAME)
if qs.exists():
return qs.first()
else:
import ipdb; ipdb.set_trace()
def get_possible_color_tag(self, possible_color_id):
if possible_color_id:
qs = tag_models.Tag.objects.filter(
old_id=possible_color_id,
category__index_name=WineColorSerializer.CATEGORY_INDEX_NAME)
if qs.exists(): if qs.exists():
return qs.first() return qs.first()
def get_possible_color_tag(self, possible_color_id):
qs = tag_models.Tag.objects.filter(
old_id=possible_color_id,
category__index_name=slugify(WineColorSerializer.TAG_CATEGORY))
if qs.exists():
return qs.first()
def get_wine_standard(self, parent_id): def get_wine_standard(self, parent_id):
qs = models.WineStandard.objects.filter(old_id=parent_id) if parent_id:
if qs.exists(): qs = models.ProductStandard.objects.filter(old_id=parent_id)
return qs.first() if qs.exists():
return qs.first()
class ProductBrandSerializer(TransferSerializerMixin): class ProductBrandSerializer(TransferSerializerMixin):
@ -171,7 +246,7 @@ class ProductSerializer(TransferSerializerMixin):
queryset=transfer_models.Establishments.objects.all(), queryset=transfer_models.Establishments.objects.all(),
allow_null=True) allow_null=True)
classification_id = serializers.PrimaryKeyRelatedField( classification_id = serializers.PrimaryKeyRelatedField(
queryset=transfer_models.WineClassification.objects.all(), queryset=transfer_models.ProductClassification.objects.all(),
allow_null=True) allow_null=True)
wine_region_id = serializers.PrimaryKeyRelatedField( wine_region_id = serializers.PrimaryKeyRelatedField(
queryset=transfer_models.WineLocations.objects.all(), queryset=transfer_models.WineLocations.objects.all(),
@ -183,7 +258,7 @@ class ProductSerializer(TransferSerializerMixin):
queryset=transfer_models.WineColor.objects.all(), queryset=transfer_models.WineColor.objects.all(),
allow_null=True) allow_null=True)
appellation_id = serializers.PrimaryKeyRelatedField( appellation_id = serializers.PrimaryKeyRelatedField(
queryset=transfer_models.WineClassification.objects.all(), queryset=transfer_models.ProductClassification.objects.all(),
allow_null=True) allow_null=True)
village_id = serializers.PrimaryKeyRelatedField( village_id = serializers.PrimaryKeyRelatedField(
queryset=transfer_models.WineLocations.objects.all(), queryset=transfer_models.WineLocations.objects.all(),
@ -192,58 +267,84 @@ class ProductSerializer(TransferSerializerMixin):
queryset=transfer_models.WineLocations.objects.all(), queryset=transfer_models.WineLocations.objects.all(),
allow_null=True) allow_null=True)
wine_quality_id = serializers.PrimaryKeyRelatedField( wine_quality_id = serializers.PrimaryKeyRelatedField(
queryset=transfer_models.WineClassification.objects.all(), queryset=transfer_models.ProductClassification.objects.all(),
allow_null=True) allow_null=True)
brand = serializers.CharField(allow_null=True) brand = serializers.CharField(allow_null=True)
name = serializers.CharField(allow_null=True) name = serializers.CharField(allow_null=True)
vintage = serializers.CharField(allow_null=True) vintage = serializers.CharField(allow_null=True)
type = serializers.CharField(allow_null=True) type = serializers.CharField(allow_null=True)
price = serializers.CharField(allow_null=True)
average_price_in_shops = serializers.CharField(allow_null=True)
wine_sub_region_id = serializers.CharField(allow_null=True) wine_sub_region_id = serializers.CharField(allow_null=True)
state = serializers.CharField() state = serializers.CharField()
bottles_produced = serializers.CharField(allow_null=True) bottles_produced = serializers.CharField(allow_null=True)
unique_key = serializers.CharField(allow_null=True)
class Meta: class Meta:
model = models.Product model = models.Product
fields = ( fields = (
'establishment_id', 'establishment_id', # done
'classification_id', 'classification_id', # done
'wine_region_id', 'wine_region_id', # done
'wine_type_id', 'wine_type_id', # done
'wine_color_id', 'wine_color_id', # done
'appellation_id', 'appellation_id', # done
'village_id', 'village_id', # done
'vineyard_id', # 'vineyard_id', duplicate wine_village
'wine_quality_id', 'wine_quality_id', # done
'brand', 'brand', # done
'name', 'name', # done
'vintage', 'vintage', # done
'type', 'type', # done
'price', 'wine_sub_region_id', # done
'average_price_in_shops', 'state', # done
'wine_sub_region_id', 'bottles_produced', # done
'state', 'unique_key', # done
'bottles_produced',
) )
def validate(self, attrs): def validate(self, attrs):
establishment_old_id = attrs.pop('establishment_id', None) establishment = attrs.pop('establishment_id', None)
state = attrs.pop('state', None) state = attrs.pop('state', None)
brand = attrs.pop('brand', None) brand = attrs.pop('brand', None)
classification = attrs.pop('classification_id', None)
vintage = attrs.pop('vintage_year', None)
product_type = attrs.pop('type')
wine_region = attrs.pop('wine_region_id', None)
wine_sub_region_id = attrs.pop('wine_sub_region_id', None)
bottles_produced = attrs.pop('bottles_produced', None)
wine_type = attrs.pop('wine_type_id', None)
wine_color = attrs.pop('wine_color_id', None)
appellation = attrs.pop('appellation_id', None)
village = attrs.pop('village_id', None)
wine_quality = attrs.pop('wine_quality_id', None)
attrs['establishment'] = self.get_establishment(establishment_old_id) attrs['old_unique_key'] = attrs.pop('unique_key')
attrs['establishment'] = self.get_establishment(establishment)
attrs['state'] = self.get_state(state) attrs['state'] = self.get_state(state)
attrs['brand'] = self.get_brand(brand) attrs['brand'] = self.get_brand(brand)
import ipdb; ipdb.set_trace() attrs['wine_classification'] = self.get_wine_classification(classification)
attrs['wine_quiality'] = self.get_wine_standard(classification,
models.ProductStandard.WINEQUALITY)
attrs['wine_appellation'] = self.get_wine_standard(appellation,
models.ProductStandard.APPELLATION)
attrs['product_type'] = self.get_product_type(product_type)
attrs['vintage'] = self.get_vintage_year(vintage)
attrs['wine_region'] = self.get_wine_region(wine_region)
attrs['wine_sub_region'] = self.get_wine_sub_region(wine_sub_region_id)
attrs['bottles_produced_tag'] = self.get_tag(bottles_produced,
WineBottlesProducedSerializer.CATEGORY_INDEX_NAME)
attrs['wine_type_tag'] = self.get_tag(wine_type,
WineTypeSerializer.CATEGORY_INDEX_NAME)
attrs['wine_color_tag'] = self.get_tag(wine_color,
WineColorSerializer.CATEGORY_INDEX_NAME)
attrs['wine_village'] = self.get_wine_village(village)
return attrs return attrs
def get_establishment(self, establishment_old_id): def get_establishment(self, establishment):
qs = establishment_models.Establishment.objects.filter( if establishment:
old_id=establishment_old_id) qs = establishment_models.Establishment.objects.filter(
if qs.exists(): old_id=establishment.id)
return qs.first() if qs.exists():
return qs.first()
def get_state(self, state): def get_state(self, state):
if state == 'published': if state == 'published':
@ -253,6 +354,80 @@ class ProductSerializer(TransferSerializerMixin):
return models.Product.WAITING return models.Product.WAITING
def get_brand(self, brand): def get_brand(self, brand):
qs = models.ProductBrand.objects.filter(brand__icontains=brand) if brand:
if qs.exists(): qs = models.ProductBrand.objects.filter(brand__icontains=brand)
return qs.first() if qs.exists():
return qs.first()
def get_wine_classification(self, classification):
if classification:
classification_qs = models.ProductClassification.objects.filter(
old_id=classification.id)
if classification_qs.exists():
return classification_qs.first()
def get_vintage_year(self, vintage):
if vintage.isdigit():
if len(vintage) == 2:
if vintage == '16':
return 2016
elif len(vintage) == 4:
if 1900 < int(vintage) < 2100:
return int(vintage)
elif vintage == '1584':
return 1984
elif vintage == '1017':
return 2017
elif len(vintage) == 5:
if vintage == '20115':
return 2015
elif vintage == '20174':
return 2017
elif vintage.endswith('er'):
return self.get_vintage_year(vintage[:-2])
def get_product_type_tag(self, product_type):
if product_type:
qs = models.ProductType.objects.filter(
index_name__icontains=product_type)
if qs.exists():
return qs.first()
def get_wine_region(self, wine_region):
if wine_region:
wine_region_qs = location_models.WineRegion.objects.filter(
old_id=wine_region.id)
if wine_region_qs.exists():
return wine_region_qs.first()
def get_wine_sub_region(self, wine_sub_region_id):
if wine_sub_region_id:
sub_region_qs = location_models.WineSubRegion.objects.filter(
old_id=wine_sub_region_id)
if sub_region_qs.exists():
return sub_region_qs.first()
def get_wine_village(self, village):
if village:
village_qs = location_models.WineVillage.objects.filter(
old_id=village.id)
if village_qs.exists():
return village_qs.first()
def get_tag(self, tag, category_index_name: str):
tag = tag.value if hasattr(tag, 'value') else tag
if tag:
qs = tag_models.Tag.objects.filter(
value=tag,
category__index_name=category_index_name)
if qs.exists():
return qs.first()
def get_wine_standard(self, standard, standard_type):
if standard:
standard = standard.id if hasattr(standard, 'id') else standard
standard_qs = models.ProductStandard.objects.filter(
standard_type=standard_type,
old_id=standard.id)
if standard_qs.exists():
return standard_qs.first()