diff --git a/apps/location/migrations/0021_auto_20191111_0731.py b/apps/location/migrations/0021_auto_20191111_0731.py new file mode 100644 index 00000000..8585fa7f --- /dev/null +++ b/apps/location/migrations/0021_auto_20191111_0731.py @@ -0,0 +1,69 @@ +# Generated by Django 2.2.4 on 2019-11-11 07:31 + +import django.contrib.gis.db.models.fields +from django.db import migrations, models +import django.db.models.deletion +import utils.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('location', '0020_merge_20191030_1714'), + ] + + operations = [ + migrations.CreateModel( + name='WineSubRegion', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='name')), + ('old_id', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id')), + ], + options={ + 'verbose_name': 'wine region', + 'verbose_name_plural': 'wine regions', + }, + ), + migrations.CreateModel( + name='WineVillage', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='name')), + ('old_id', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id')), + ], + options={ + 'verbose_name': 'wine village', + 'verbose_name_plural': 'wine villages', + }, + ), + migrations.RemoveField( + model_name='wineappellation', + name='wine_region', + ), + migrations.AddField( + model_name='wineregion', + name='coordinates', + field=django.contrib.gis.db.models.fields.PointField(blank=True, default=None, null=True, srid=4326, verbose_name='Coordinates'), + ), + migrations.AddField( + model_name='wineregion', + name='description', + field=utils.models.TJSONField(blank=True, default=None, help_text='{"en-GB":"some text"}', null=True, verbose_name='description'), + ), + migrations.AddField( + model_name='wineregion', + name='old_id', + field=models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id'), + ), + migrations.AlterField( + model_name='wineregion', + name='country', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='location.Country', verbose_name='country'), + ), + migrations.AlterField( + model_name='wineregion', + name='name', + field=models.CharField(max_length=255, verbose_name='name'), + ), + ] diff --git a/apps/location/migrations/0022_auto_20191111_0731.py b/apps/location/migrations/0022_auto_20191111_0731.py new file mode 100644 index 00000000..378ed1a3 --- /dev/null +++ b/apps/location/migrations/0022_auto_20191111_0731.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.4 on 2019-11-11 07:31 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('location', '0021_auto_20191111_0731'), + ('product', '0009_auto_20191111_0731'), + ] + + operations = [ + migrations.DeleteModel( + name='WineAppellation', + ), + migrations.AddField( + model_name='winevillage', + name='wine_region', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='location.WineRegion', verbose_name='wine region'), + ), + migrations.AddField( + model_name='winesubregion', + name='wine_region', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='location.WineRegion', verbose_name='wine sub region'), + ), + ] diff --git a/apps/product/management/commands/add_product.py b/apps/product/management/commands/add_product.py deleted file mode 100644 index 981487ec..00000000 --- a/apps/product/management/commands/add_product.py +++ /dev/null @@ -1,54 +0,0 @@ -from django.core.management.base import BaseCommand -from product.models import ProductType, ProductSubType - - -def add_type(): - product_type = ProductType.objects.create( - name={'"en-GB"': "Wine"}, - index_name=ProductType.WINE - ) - return product_type.save() - - -def add_subtype(id_type): - subtypes = ProductSubType.objects.bulk_create([ - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.EXTRA_BRUT}, - index_name=ProductSubType.EXTRA_BRUT), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.BRUT}, - index_name=ProductSubType.BRUT), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.BRUT_NATURE}, - index_name=ProductSubType.BRUT_NATURE), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.DEMI_SEC}, - index_name=ProductSubType.DEMI_SEC), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.EXTRA_DRY}, - index_name=ProductSubType.EXTRA_DRY), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.DOSAGE_ZERO}, - index_name=ProductSubType.DOSAGE_ZERO), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.SEC}, - index_name=ProductSubType.SEC), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.SEC}, - index_name=ProductSubType.SEC), - ProductSubType(product_type=id_type, - name={"en-GB", ProductSubType.MOELLEUX}, - index_name=ProductSubType.MOELLEUX), - ]) - - -class Command(BaseCommand): - help = 'Add product data' - - def handle(self, *args, **kwarg): - product_type = add_type() - add_subtype(product_type.id) - - - - diff --git a/apps/product/management/commands/add_product_sub_type.py b/apps/product/management/commands/add_product_sub_type.py new file mode 100644 index 00000000..9601020c --- /dev/null +++ b/apps/product/management/commands/add_product_sub_type.py @@ -0,0 +1,34 @@ +from django.conf import settings +from django.core.management.base import BaseCommand + +from product.models import ProductType, ProductSubType + + +class Command(BaseCommand): + help = 'Add product sub type data' + + def handle(self, *args, **kwarg): + 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 + self.stdout.write(self.style.WARNING(f'Errors occurred: {error_counter}\nCreated: {create_counter}')) diff --git a/apps/product/management/commands/add_product_type.py b/apps/product/management/commands/add_product_type.py new file mode 100644 index 00000000..14ba53d3 --- /dev/null +++ b/apps/product/management/commands/add_product_type.py @@ -0,0 +1,20 @@ +from django.conf import settings +from django.core.management.base import BaseCommand + +from product.models import ProductType + + +class Command(BaseCommand): + help = 'Add product type data' + + def handle(self, *args, **kwarg): + product_types = ['wine', 'souvenir'] + create_counter = 0 + for product_type in product_types: + subtype, created = ProductType.objects.get_or_create(**{ + 'name': {settings.FALLBACK_LOCALE: product_type}, + 'index_name': product_type + }) + if created: + created += 1 + self.stdout.write(self.style.WARNING(f'Created: {create_counter}')) diff --git a/apps/product/migrations/0009_auto_20191111_0731.py b/apps/product/migrations/0009_auto_20191111_0731.py new file mode 100644 index 00000000..53a79c0b --- /dev/null +++ b/apps/product/migrations/0009_auto_20191111_0731.py @@ -0,0 +1,179 @@ +# Generated by Django 2.2.4 on 2019-11-11 07:31 + +import django.contrib.gis.db.models.fields +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('gallery', '0006_merge_20191027_1758'), + ('location', '0021_auto_20191111_0731'), + ('tag', '0009_auto_20191111_0731'), + ('product', '0008_auto_20191031_1410'), + ] + + operations = [ + migrations.CreateModel( + name='ProductStandard', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='name')), + ('standard_type', models.PositiveSmallIntegerField(choices=[(0, 'Appellation'), (1, 'Wine quality'), (2, 'Yard classification')], verbose_name='standard type')), + ('coordinates', django.contrib.gis.db.models.fields.PointField(blank=True, default=None, null=True, srid=4326, verbose_name='Coordinates')), + ('old_id', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id')), + ], + options={ + 'verbose_name': 'wine standard', + 'verbose_name_plural': 'wine standards', + }, + ), + migrations.CreateModel( + name='Unit', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='name')), + ('value', models.CharField(max_length=255, verbose_name='value')), + ], + options={ + 'verbose_name': 'unit', + 'verbose_name_plural': 'units', + }, + ), + migrations.RemoveField( + model_name='product', + name='characteristics', + ), + migrations.RemoveField( + model_name='product', + name='wine_appellation', + ), + migrations.AddField( + model_name='product', + name='old_id', + field=models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id'), + ), + migrations.AddField( + model_name='product', + name='old_unique_key', + field=models.CharField(blank=True, default=None, help_text='attribute from legacy db', max_length=255, null=True, unique=True), + ), + migrations.AddField( + model_name='product', + name='state', + field=models.PositiveIntegerField(choices=[(0, 'Published'), (1, 'Out_of_production'), (2, 'Waiting')], default=2, help_text='attribute from legacy db', verbose_name='state'), + ), + migrations.AddField( + model_name='product', + name='tags', + field=models.ManyToManyField(related_name='products', to='tag.Tag', verbose_name='Tag'), + ), + migrations.AddField( + model_name='product', + name='vintage', + field=models.IntegerField(blank=True, default=None, null=True, validators=[django.core.validators.MinValueValidator(1700), django.core.validators.MaxValueValidator(2100)], verbose_name='vintage year'), + ), + migrations.AddField( + model_name='product', + name='wine_sub_region', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='wines', to='location.WineSubRegion', verbose_name='wine sub region'), + ), + migrations.AddField( + model_name='product', + name='wine_village', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='location.WineVillage', verbose_name='wine appellation'), + ), + migrations.AddField( + model_name='producttype', + name='tag_categories', + field=models.ManyToManyField(related_name='product_types', to='tag.TagCategory', verbose_name='Tag'), + ), + 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'), + ), + migrations.AlterField( + model_name='product', + name='name', + field=models.CharField(default=None, max_length=255, null=True, verbose_name='name'), + ), + migrations.AlterField( + model_name='product', + name='product_type', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='products', to='product.ProductType', verbose_name='Type'), + ), + migrations.AlterField( + model_name='product', + name='wine_region', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='wines', to='location.WineRegion', verbose_name='wine region'), + ), + migrations.AlterField( + model_name='productsubtype', + name='index_name', + field=models.CharField(choices=[('rum', 'Rum'), ('plate', 'Plate'), ('other', 'Other')], db_index=True, max_length=50, unique=True, verbose_name='Index name'), + ), + migrations.AlterField( + model_name='producttype', + name='index_name', + field=models.CharField(choices=[('food', 'Food'), ('wine', 'Wine'), ('liquor', 'Liquor'), ('souvenir', 'Souvenir'), ('book', 'Book')], db_index=True, max_length=50, unique=True, verbose_name='Index name'), + ), + migrations.CreateModel( + name='ProductGallery', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_main', models.BooleanField(default=False, verbose_name='Is the main image')), + ('image', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='product_gallery', to='gallery.Image', verbose_name='gallery')), + ('product', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='product_gallery', to='product.Product', verbose_name='product')), + ], + options={ + 'verbose_name': 'product gallery', + 'verbose_name_plural': 'product galleries', + 'unique_together': {('product', 'image'), ('product', 'is_main')}, + }, + ), + migrations.CreateModel( + name='ProductClassificationType', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True, verbose_name='classification type')), + ('product_sub_type', models.ForeignKey(blank=True, default=None, help_text='Legacy attribute - possible_type (product type).Product type in our case is product subtype.', null=True, on_delete=django.db.models.deletion.PROTECT, to='product.ProductSubType', verbose_name='product subtype')), + ('product_type', models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='product.ProductType', verbose_name='product type')), + ], + options={ + 'verbose_name': 'wine classification type', + 'verbose_name_plural': 'wine classification types', + }, + ), + migrations.CreateModel( + name='ProductClassification', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('old_id', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id')), + ('classification_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='product.ProductClassificationType', verbose_name='classification type')), + ('standard', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, to='product.ProductStandard', verbose_name='standard')), + ('tags', models.ManyToManyField(related_name='product_classifications', to='tag.Tag', verbose_name='Tag')), + ], + options={ + 'verbose_name': 'product classification', + 'verbose_name_plural': 'product classifications', + }, + ), + migrations.AddField( + model_name='product', + name='classifications', + field=models.ManyToManyField(blank=True, to='product.ProductClassification', verbose_name='classifications'), + ), + migrations.AddField( + model_name='product', + name='gallery', + field=models.ManyToManyField(through='product.ProductGallery', to='gallery.Image'), + ), + migrations.AddField( + model_name='product', + name='standards', + field=models.ManyToManyField(blank=True, help_text='attribute from legacy db', to='product.ProductStandard', verbose_name='standards'), + ), + ] diff --git a/apps/product/models.py b/apps/product/models.py index 00d49eba..1098252e 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -206,7 +206,7 @@ class Product(TranslatedFieldsMixin, BaseAttributes): def __str__(self): """Override str dunder method.""" - return self.name + return f'{self.name}' def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) diff --git a/apps/product/transfer_data.py b/apps/product/transfer_data.py index e092dae8..1e52b362 100644 --- a/apps/product/transfer_data.py +++ b/apps/product/transfer_data.py @@ -1,48 +1,9 @@ from pprint import pprint -from django.conf import settings from transfer import models as transfer_models 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(): queryset = transfer_models.EstablishmentBacklinks.objects.filter(type="Partner") @@ -180,10 +141,6 @@ def transfer_plate_image(): data_types = { "partner": [transfer_partner], - "product_type": [ - transfer_product_types, - transfer_product_subtype, - ], "wine_characteristics": [ transfer_wine_sugar_content, transfer_wine_color, diff --git a/apps/tag/migrations/0009_auto_20191111_0731.py b/apps/tag/migrations/0009_auto_20191111_0731.py new file mode 100644 index 00000000..f4b775b4 --- /dev/null +++ b/apps/tag/migrations/0009_auto_20191111_0731.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.4 on 2019-11-11 07:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tag', '0008_auto_20191101_1244'), + ] + + operations = [ + migrations.AddField( + model_name='tag', + name='old_id', + field=models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id'), + ), + migrations.AddField( + model_name='tag', + name='priority', + field=models.PositiveIntegerField(default=0, null=True), + ), + ] diff --git a/apps/transfer/management/commands/transfer.py b/apps/transfer/management/commands/transfer.py index 80c2e131..a3726dd7 100644 --- a/apps/transfer/management/commands/transfer.py +++ b/apps/transfer/management/commands/transfer.py @@ -27,7 +27,6 @@ class Command(BaseCommand): LONG_DATA_TYPES = [ 'update_country_flag', - 'product_type', 'wine_characteristics', 'product', ] diff --git a/apps/transfer/mixins.py b/apps/transfer/mixins.py index ccc402da..00492acf 100644 --- a/apps/transfer/mixins.py +++ b/apps/transfer/mixins.py @@ -74,20 +74,19 @@ class TransferSerializerMixin(serializers.ModelSerializer): elif vintage.endswith('er'): return self.get_vintage_year(vintage[:-2]) - def get_product_type(self, product_type): - if isinstance(product_type, ProductType): - return product_type - if product_type: + def get_product_type(self, index_name): + if index_name: qs = ProductType.objects.filter( - index_name__icontains=product_type) + index_name__icontains=index_name) if qs.exists(): return qs.first() def get_product_sub_type(self, product_type, product_sub_type): - product_type = self.get_product_type(product_type) + if not isinstance(product_type, ProductType): + product_type = self.get_product_type(product_type) if product_type and product_sub_type: qs = ProductSubType.objects.filter( product_type=product_type, - index_name__icontains=product_type) + index_name__icontains=product_sub_type) if qs.exists(): return qs.first() diff --git a/apps/transfer/serializers/establishment.py b/apps/transfer/serializers/establishment.py index a228a577..211226e7 100644 --- a/apps/transfer/serializers/establishment.py +++ b/apps/transfer/serializers/establishment.py @@ -109,17 +109,12 @@ class EstablishmentSerializer(serializers.ModelSerializer): types = { 'Restaurant': EstablishmentType.RESTAURANT, 'Shop': EstablishmentType.ARTISAN, - 'Producer': EstablishmentType.PRODUCER, + 'Wineyard': EstablishmentType.PRODUCER, } - if old_type == 'Wineyard': - index_name = types['Producer'] - elif old_type in types.keys(): - index_name = types[old_type] - else: - return None - - obj, _ = EstablishmentType.objects.get_or_create(index_name=index_name) - return obj.id + index_name = types.get(old_type) + if index_name: + obj, _ = EstablishmentType.objects.get_or_create(index_name=index_name) + return obj.id @staticmethod def get_schedules(schedules): diff --git a/apps/transfer/serializers/product.py b/apps/transfer/serializers/product.py index c7c24318..873c0746 100644 --- a/apps/transfer/serializers/product.py +++ b/apps/transfer/serializers/product.py @@ -489,6 +489,7 @@ class PlateImageSerializer(serializers.ModelSerializer): model = models.ProductGallery fields = ( 'id', + 'name', 'attachment_suffix_url', )