From 45f65658f0069ec8cd458d997ec9a6e30bda5108 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Fri, 31 Jan 2020 11:33:20 +0300 Subject: [PATCH] added "status" field to Establishment model, refactored serializers and filters associated with field "is_publish", modified transfer --- .../commands/add_establishment_status.py | 43 +++++++++++++++++++ .../migrations/0089_establishment_status.py | 18 ++++++++ apps/establishment/models.py | 20 +++++++-- apps/establishment/serializers/back.py | 4 ++ apps/establishment/serializers/common.py | 3 ++ apps/establishment/transfer_data.py | 1 + apps/transfer/serializers/establishment.py | 17 +++++++- 7 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 apps/establishment/management/commands/add_establishment_status.py create mode 100644 apps/establishment/migrations/0089_establishment_status.py diff --git a/apps/establishment/management/commands/add_establishment_status.py b/apps/establishment/management/commands/add_establishment_status.py new file mode 100644 index 00000000..160c2d1f --- /dev/null +++ b/apps/establishment/management/commands/add_establishment_status.py @@ -0,0 +1,43 @@ +from django.core.management.base import BaseCommand +from tqdm import tqdm + +from establishment.models import Establishment +from transfer.models import Establishments + + +class Command(BaseCommand): + help = """ + Update establishment status field.. + Run command ./manage.py add_establishment_status + """ + + def get_status(self, old_status): + if old_status: + old_status = old_status.lower() + if old_status == 'abandoned': + return Establishment.ABANDONED + elif old_status == 'closed': + return Establishment.CLOSED + elif old_status == 'published': + return Establishment.PUBLISHED + elif old_status == 'unpicked': + return Establishment.UNPICKED + return Establishment.WAITING + + def handle(self, *args, **kwargs): + queryset = Establishment.objects.exclude(old_id__isnull=True) + to_update = [] + non_existed_objects = 0 + + for establishment in tqdm(queryset, desc='Iterate over existed establishments'): + legacy_establishment_qs = Establishments.objects.filter(id=establishment.old_id) + if legacy_establishment_qs.exists(): + legacy_establishment = legacy_establishment_qs.first() + establishment.status = self.get_status(legacy_establishment.state) + to_update.append(establishment) + else: + non_existed_objects += 1 + + Establishment.objects.bulk_update(to_update, ['status', ]) + self.stdout.write(self.style.WARNING(f'Non existed {non_existed_objects} objects.')) + self.stdout.write(self.style.SUCCESS(f'Updated {len(to_update)} objects.')) diff --git a/apps/establishment/migrations/0089_establishment_status.py b/apps/establishment/migrations/0089_establishment_status.py new file mode 100644 index 00000000..4e0914d0 --- /dev/null +++ b/apps/establishment/migrations/0089_establishment_status.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.7 on 2020-01-31 07:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('establishment', '0088_merge_20200130_1318'), + ] + + operations = [ + migrations.AddField( + model_name='establishment', + name='status', + field=models.PositiveSmallIntegerField(choices=[(0, 'Abandoned'), (1, 'Closed'), (2, 'Published'), (3, 'Unpicked'), (4, 'Waiting')], default=4, verbose_name='Status'), + ), + ] diff --git a/apps/establishment/models.py b/apps/establishment/models.py index a7097744..e3831891 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -191,7 +191,7 @@ class EstablishmentQuerySet(models.QuerySet): """ Return QuerySet with published establishments. """ - return self.filter(is_publish=True) + return self.filter(status=Establishment.PUBLISHED) def has_published_reviews(self): """ @@ -542,7 +542,19 @@ class Establishment(GalleryMixin, ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin, HasTagsMixin, FavoritesMixin): """Establishment model.""" - # todo: delete image URL fields after moving on gallery + ABANDONED = 0 + CLOSED = 1 + PUBLISHED = 2 + UNPICKED = 3 + WAITING = 4 + + STATUS_CHOICES = ( + (ABANDONED, _('Abandoned')), + (CLOSED, _('Closed')), + (PUBLISHED, _('Published')), + (UNPICKED, _('Unpicked')), + (WAITING, _('Waiting')), + ) old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) name = models.CharField(_('name'), max_length=255, default='') @@ -589,7 +601,9 @@ class Establishment(GalleryMixin, ProjectBaseMixin, URLImageMixin, null=True, default=None, ) booking = models.URLField(blank=True, null=True, default=None, max_length=255, verbose_name=_('Booking URL')) - is_publish = models.BooleanField(default=False, verbose_name=_('Publish status')) + is_publish = models.BooleanField(default=False, verbose_name=_('Publish status')) # deprecated + status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=WAITING, + verbose_name=_('Status')) schedule = models.ManyToManyField(to='timetable.Timetable', blank=True, verbose_name=_('Establishment schedule'), related_name='schedule') diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index f9958d09..3a2b1620 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -100,6 +100,8 @@ class EstablishmentListCreateSerializer(model_serializers.EstablishmentBaseSeria 'tags', 'tz', 'address_id', + 'status', + 'status_display', ] def create(self, validated_data): @@ -180,6 +182,8 @@ class EstablishmentRUDSerializer(model_serializers.EstablishmentBaseSerializer): 'address', 'transportation', 'tags', + 'status', + 'status_display', ] def update(self, instance, validated_data): diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 3fb7a152..9f557a28 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -335,6 +335,7 @@ class EstablishmentBaseSerializer(ProjectModelSerializer): tz = serializers.CharField(read_only=True, source='timezone_as_str') new_image = serializers.SerializerMethodField(allow_null=True, read_only=True) distillery_type = TagBaseSerializer(read_only=True, many=True, allow_null=True) + status_display = serializers.CharField(read_only=True, source='get_status_display') def get_image(self, obj): if obj.main_image: @@ -391,6 +392,8 @@ class EstablishmentBaseSerializer(ProjectModelSerializer): 'tz', 'wine_regions', 'distillery_type', + 'status_display', + 'status', ] diff --git a/apps/establishment/transfer_data.py b/apps/establishment/transfer_data.py index 6b521edb..a7aa92ff 100644 --- a/apps/establishment/transfer_data.py +++ b/apps/establishment/transfer_data.py @@ -14,6 +14,7 @@ from transfer.serializers.plate import PlateSerializer def transfer_establishment(): + """Transfer establishments.""" result = [] # todo: filter(location__city__name__icontains='paris') diff --git a/apps/transfer/serializers/establishment.py b/apps/transfer/serializers/establishment.py index f268bdc9..84358c7a 100644 --- a/apps/transfer/serializers/establishment.py +++ b/apps/transfer/serializers/establishment.py @@ -65,12 +65,11 @@ class EstablishmentSerializer(serializers.ModelSerializer): 'slug': generate_unique_slug(Establishment, data['slug'] if data['slug'] else data['name']), 'address_id': self.get_address(data['location']), 'establishment_type_id': self.get_type(old_type), - 'is_publish': data.get('state') == 'published', + 'status': self.get_status(data.pop('state', None)), 'subtype': self.get_subtype(old_type), 'phone': self.get_phone(phone), }) data.pop('location') - data.pop('state') return data @transaction.atomic @@ -189,6 +188,20 @@ class EstablishmentSerializer(serializers.ModelSerializer): fmt = PhoneNumber.format_map[getattr(settings, 'PHONENUMBER_DB_FORMAT', 'INTERNATIONAL')] return phone_obj.format_as(fmt) + @staticmethod + def get_status(state: str): + if state: + state = state.lower() + if state == 'abandoned': + return Establishment.ABANDONED + elif state == 'closed': + return Establishment.CLOSED + elif state == 'published': + return Establishment.PUBLISHED + elif state == 'unpicked': + return Establishment.UNPICKED + return Establishment.WAITING + class EstablishmentNoteSerializer(serializers.ModelSerializer):