diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 611830fb..6342acc4 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -534,7 +534,7 @@ class EstablishmentQuerySet(models.QuerySet): """Return QuerySet with establishments that user has an access.""" from account.models import UserRole - if not user.is_superuser: + if not user.is_superuser and not user.is_anonymous: filters = {'address__city__country__code': country_code} if user.is_establishment_administrator and not user.is_establishment_manager: filters.update({ diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 2cca450c..bf858c0d 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -232,6 +232,8 @@ class EstablishmentRUDSerializer(model_serializers.EstablishmentBaseSerializer): last_review = ReviewBaseSerializer(read_only=True) + must_of_the_week = serializers.BooleanField(required=False, ) + class Meta(model_serializers.EstablishmentBaseSerializer.Meta): fields = [ 'id', @@ -264,6 +266,7 @@ class EstablishmentRUDSerializer(model_serializers.EstablishmentBaseSerializer): 'must_of_the_week', 'last_update_by_gm', 'last_update_by_manager', + 'public_mark', ] def to_representation(self, instance): diff --git a/apps/location/views/back.py b/apps/location/views/back.py index 0203f73b..774b2dbd 100644 --- a/apps/location/views/back.py +++ b/apps/location/views/back.py @@ -17,7 +17,50 @@ from utils.permissions import ( # Address class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView): - """Create view for model Address.""" + """ + ## List/Create view + ### *GET* + #### Description + Get paginated list of addresses + ##### Response + E.g.: + ``` + { + "count": 58, + "next": 2, + "previous": null, + "results": [ + { + "id": 1, + ... + } + ] + } + ``` + ### *POST* + #### Description + Create a new address + ##### Request + Required + * latitude (`float`) - latitude + * longitude (`float`) - longitude + * city_id (`int`) - identifier of city + + Available + * district_name (`str`) - city district name + * street_name_1 (`str`) - street name + * street_name_2 (`str`) - street name (additional) + * number (`int`) - city name + * postal_code (`str`) - city postal code + ##### Response + E.g.: + ``` + { + "id": 1, + ... + } + ``` + """ serializer_class = serializers.AddressDetailSerializer queryset = models.Address.objects.all() permission_classes = get_permission_classes( @@ -28,7 +71,48 @@ class AddressListCreateView(common.AddressViewMixin, generics.ListCreateAPIView) class AddressRUDView(common.AddressViewMixin, generics.RetrieveUpdateDestroyAPIView): - """RUD view for model Address.""" + """ + ## Retrieve/Update/Destroy view + ### *GET* + #### Description + Return serialized object of an address by an identifier. + ##### Response + E.g.: + ``` + { + "id": 1, + ... + } + ``` + ### *PUT*/*PATCH* + #### Description + Completely/Partially update an address object by an identifier. + ##### Request + Available + * latitude (`float`) - latitude + * longitude (`float`) - longitude + * city_id (`int`) - identifier of city + * district_name (`str`) - city district name + * street_name_1 (`str`) - street name + * street_name_2 (`str`) - street name (additional) + * number (`int`) - city name + * postal_code (`str`) - city postal code + ##### Response + E.g. + ``` + { + "id": 1, + ... + } + ``` + ### *DELETE* + #### Description + Delete an address object by an identifier. + ##### Response + ``` + No content + ``` + """ serializer_class = serializers.AddressDetailSerializer queryset = models.Address.objects.all() permission_classes = get_permission_classes( diff --git a/apps/review/migrations/0021_review_visited_at.py b/apps/review/migrations/0021_review_visited_at.py new file mode 100644 index 00000000..c8889d20 --- /dev/null +++ b/apps/review/migrations/0021_review_visited_at.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.7 on 2020-02-10 08:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('review', '0020_reviewtextauthor'), + ] + + operations = [ + migrations.AddField( + model_name='review', + name='visited_at', + field=models.DateField(blank=True, null=True), + ), + ] diff --git a/apps/review/models.py b/apps/review/models.py index 34f2c4b7..72fd12d6 100644 --- a/apps/review/models.py +++ b/apps/review/models.py @@ -94,6 +94,7 @@ class Review(BaseAttributes, TranslatedFieldsMixin): mark = models.FloatField(verbose_name=_('mark'), blank=True, null=True, default=None) priority = models.PositiveSmallIntegerField(_('Priority'), blank=True, null=True, default=None) old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) + visited_at = models.DateField(blank=True, null=True) objects = ReviewQuerySet.as_manager() @@ -101,6 +102,17 @@ class Review(BaseAttributes, TranslatedFieldsMixin): def status_display(self): return self.REVIEW_STATUSES[self.status][1] + @property + def visited_on(self): + from account.models import User + from account.serializers import UserBaseSerializer + if isinstance(self.reviewer, User): + return { + 'user': UserBaseSerializer(self.reviewer).data, + 'date': self.visited_at, + } + return None + class Meta: """Meta class.""" verbose_name = _('Review') diff --git a/apps/review/serializers/common.py b/apps/review/serializers/common.py index 46a9741d..bce7ac6f 100644 --- a/apps/review/serializers/common.py +++ b/apps/review/serializers/common.py @@ -6,6 +6,7 @@ from review.models import Review, Inquiries, GridItems class ReviewBaseSerializer(serializers.ModelSerializer): text_translated = serializers.CharField(read_only=True) status_display = serializers.CharField(read_only=True) + visited_on = serializers.DictField(read_only=True, allow_null=True) class Meta: model = Review @@ -23,6 +24,7 @@ class ReviewBaseSerializer(serializers.ModelSerializer): 'country', 'content_type', 'object_id', + 'visited_on', ) diff --git a/apps/utils/models.py b/apps/utils/models.py index adbfbbeb..de583308 100644 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -542,22 +542,42 @@ class AwardsModelMixin: class CarouselMixin: + def __must_of_the_week_info_from_self(self) -> dict: + from main.models import Country + + return { + 'content_type': ContentType.objects.get_for_model(self), + 'object_id': getattr(self, 'pk'), + 'country': getattr(self, 'country', get_object_or_404(Country, id=getattr(self, 'country_id', 0))), + } + + def __must_of_the_week_has_fields(self) -> bool: + return hasattr(self, 'pk') and (hasattr(self, 'country') or hasattr(self, 'country_id')) + @property def must_of_the_week(self) -> bool: + from main import models as main_models + """Detects whether current item in carousel""" - from main.models import Carousel - - if hasattr(self, 'pk') and (hasattr(self, 'country') or hasattr(self, 'country_id')): - kwargs = { - 'content_type': ContentType.objects.get_for_model(self), - 'object_id': self.pk, - 'country': getattr(self, 'country', getattr(self, 'country_id', None)), - } - - return Carousel.objects.filter(**kwargs).exists() + if self.__must_of_the_week_has_fields(): + kwargs = self.__must_of_the_week_info_from_self() + return main_models.Carousel.objects.filter(**kwargs).exists() return False + @must_of_the_week.setter + def must_of_the_week(self, status: bool): + from main import models as main_models + + """Update field by status""" + if status != self.must_of_the_week and self.__must_of_the_week_has_fields(): + carousel, _ = main_models.Carousel.objects.get_or_create( + **self.__must_of_the_week_info_from_self() + ) + + if not status and isinstance(carousel, main_models.Carousel): + carousel.delete() + class UpdateByMixin(models.Model): """Modify by mixin""" diff --git a/project/settings/development.py b/project/settings/development.py index 25736d95..9a507403 100644 --- a/project/settings/development.py +++ b/project/settings/development.py @@ -66,8 +66,8 @@ COOKIE_DOMAIN = '.id-east.ru' # Email settings EMAIL_USE_TLS = True EMAIL_HOST = 'smtp.gmail.com' -EMAIL_HOST_USER = 'anatolyfeteleu@gmail.com' -EMAIL_HOST_PASSWORD = 'nggrlnbehzksgmbt' +EMAIL_HOST_USER = 'dev.fr.test.gm.back.1@gmail.com' +EMAIL_HOST_PASSWORD = 'onvwzsggdhdfqemi' EMAIL_PORT = 587 MIDDLEWARE.append('utils.middleware.log_db_queries_per_API_request') diff --git a/project/settings/local.py b/project/settings/local.py index 1d5d7de5..475a03e1 100644 --- a/project/settings/local.py +++ b/project/settings/local.py @@ -117,8 +117,8 @@ ELASTICSEARCH_DSL_AUTOSYNC = False # Email settings EMAIL_USE_TLS = True EMAIL_HOST = 'smtp.gmail.com' -EMAIL_HOST_USER = 'anatolyfeteleu@gmail.com' -EMAIL_HOST_PASSWORD = 'nggrlnbehzksgmbt' +EMAIL_HOST_USER = 'dev.fr.test.gm.back.1@gmail.com' +EMAIL_HOST_PASSWORD = 'onvwzsggdhdfqemi' EMAIL_PORT = 587 # ADD TRANSFER TO INSTALLED APPS