Merge branch 'feature/permission_liquor' into 'develop'
Feature/permission liquor See merge request gm/gm-backend!175
This commit is contained in:
commit
6a68042178
18
apps/account/migrations/0026_auto_20191210_1553.py
Normal file
18
apps/account/migrations/0026_auto_20191210_1553.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-12-10 15:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0025_auto_20191210_0623'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='role',
|
||||||
|
name='role',
|
||||||
|
field=models.PositiveIntegerField(choices=[(1, 'Standard user'), (2, 'Comments moderator'), (3, 'Country admin'), (4, 'Content page manager'), (5, 'Establishment manager'), (6, 'Reviewer manager'), (7, 'Restaurant reviewer'), (8, 'Sales man'), (9, 'Winery reviewer'), (10, 'Seller'), (11, 'Liquor reviewer'), (12, 'Product reviewer')], verbose_name='Role'),
|
||||||
|
),
|
||||||
|
]
|
||||||
14
apps/account/migrations/0028_merge_20191217_1127.py
Normal file
14
apps/account/migrations/0028_merge_20191217_1127.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-12-17 11:27
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0027_auto_20191211_1444'),
|
||||||
|
('account', '0026_auto_20191210_1553'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
||||||
|
|
@ -36,6 +36,8 @@ class Role(ProjectBaseMixin):
|
||||||
SALES_MAN = 8
|
SALES_MAN = 8
|
||||||
WINERY_REVIEWER = 9 # Establishments subtype "winery"
|
WINERY_REVIEWER = 9 # Establishments subtype "winery"
|
||||||
SELLER = 10
|
SELLER = 10
|
||||||
|
LIQUOR_REVIEWER = 11
|
||||||
|
PRODUCT_REVIEWER = 12
|
||||||
|
|
||||||
ROLE_CHOICES = (
|
ROLE_CHOICES = (
|
||||||
(STANDARD_USER, _('Standard user')),
|
(STANDARD_USER, _('Standard user')),
|
||||||
|
|
@ -47,7 +49,9 @@ class Role(ProjectBaseMixin):
|
||||||
(RESTAURANT_REVIEWER, 'Restaurant reviewer'),
|
(RESTAURANT_REVIEWER, 'Restaurant reviewer'),
|
||||||
(SALES_MAN, 'Sales man'),
|
(SALES_MAN, 'Sales man'),
|
||||||
(WINERY_REVIEWER, 'Winery reviewer'),
|
(WINERY_REVIEWER, 'Winery reviewer'),
|
||||||
(SELLER, 'Seller')
|
(SELLER, 'Seller'),
|
||||||
|
(LIQUOR_REVIEWER, 'Liquor reviewer'),
|
||||||
|
(PRODUCT_REVIEWER, 'Product reviewer'),
|
||||||
)
|
)
|
||||||
role = models.PositiveIntegerField(verbose_name=_('Role'), choices=ROLE_CHOICES,
|
role = models.PositiveIntegerField(verbose_name=_('Role'), choices=ROLE_CHOICES,
|
||||||
null=False, blank=False)
|
null=False, blank=False)
|
||||||
|
|
|
||||||
20
apps/product/migrations/0021_product_site.py
Normal file
20
apps/product/migrations/0021_product_site.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-12-10 14:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('main', '0040_footer'),
|
||||||
|
('product', '0020_merge_20191209_0911'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='product',
|
||||||
|
name='site',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='main.SiteSettings'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
apps/product/migrations/0022_auto_20191210_1517.py
Normal file
18
apps/product/migrations/0022_auto_20191210_1517.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-12-10 15:17
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('product', '0021_product_site'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
14
apps/product/migrations/0023_merge_20191217_1127.py
Normal file
14
apps/product/migrations/0023_merge_20191217_1127.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-12-17 11:27
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('product', '0022_auto_20191210_1517'),
|
||||||
|
('product', '0021_auto_20191212_0926'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
||||||
|
|
@ -30,10 +30,17 @@ class ProductType(TypeDefaultImageMixin, TranslatedFieldsMixin, ProjectBaseMixin
|
||||||
SOUVENIR = 'souvenir'
|
SOUVENIR = 'souvenir'
|
||||||
BOOK = 'book'
|
BOOK = 'book'
|
||||||
|
|
||||||
|
INDEX_CHOICES = (
|
||||||
|
(FOOD, 'food'),
|
||||||
|
(WINE, 'wine'),
|
||||||
|
(LIQUOR, 'liquor'),
|
||||||
|
(SOUVENIR, 'souvenir'),
|
||||||
|
(BOOK, 'book')
|
||||||
|
)
|
||||||
name = TJSONField(blank=True, null=True, default=None,
|
name = TJSONField(blank=True, null=True, default=None,
|
||||||
verbose_name=_('Name'), help_text='{"en-GB":"some text"}')
|
verbose_name=_('Name'), help_text='{"en-GB":"some text"}')
|
||||||
index_name = models.CharField(max_length=50, unique=True, db_index=True,
|
index_name = models.CharField(max_length=50, unique=True, db_index=True,
|
||||||
verbose_name=_('Index name'))
|
verbose_name=_('Index name'), choices=INDEX_CHOICES)
|
||||||
use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
|
use_subtypes = models.BooleanField(_('Use subtypes'), default=True)
|
||||||
tag_categories = models.ManyToManyField('tag.TagCategory',
|
tag_categories = models.ManyToManyField('tag.TagCategory',
|
||||||
related_name='product_types',
|
related_name='product_types',
|
||||||
|
|
@ -289,6 +296,8 @@ class Product(GalleryMixin, TranslatedFieldsMixin, BaseAttributes,
|
||||||
default=None, null=True,
|
default=None, null=True,
|
||||||
verbose_name=_('Serial number'))
|
verbose_name=_('Serial number'))
|
||||||
|
|
||||||
|
site = models.ForeignKey(to='main.SiteSettings', null=True, blank=True, on_delete=models.CASCADE)
|
||||||
|
|
||||||
objects = ProductManager.from_queryset(ProductQuerySet)()
|
objects = ProductManager.from_queryset(ProductQuerySet)()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from product.serializers import ProductDetailSerializer, ProductTypeBaseSerializ
|
||||||
ProductSubTypeBaseSerializer
|
ProductSubTypeBaseSerializer
|
||||||
from tag.models import TagCategory
|
from tag.models import TagCategory
|
||||||
from account.serializers.common import UserShortSerializer
|
from account.serializers.common import UserShortSerializer
|
||||||
|
from main.serializers import SiteSettingsSerializer
|
||||||
|
|
||||||
class ProductBackOfficeGallerySerializer(serializers.ModelSerializer):
|
class ProductBackOfficeGallerySerializer(serializers.ModelSerializer):
|
||||||
"""Serializer class for model ProductGallery."""
|
"""Serializer class for model ProductGallery."""
|
||||||
|
|
@ -55,6 +55,7 @@ class ProductBackOfficeGallerySerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class ProductBackOfficeDetailSerializer(ProductDetailSerializer):
|
class ProductBackOfficeDetailSerializer(ProductDetailSerializer):
|
||||||
"""Product back-office detail serializer."""
|
"""Product back-office detail serializer."""
|
||||||
|
in_favorites = serializers.BooleanField(allow_null=True, read_only=True)
|
||||||
|
|
||||||
class Meta(ProductDetailSerializer.Meta):
|
class Meta(ProductDetailSerializer.Meta):
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -68,9 +69,10 @@ class ProductBackOfficeDetailSerializer(ProductDetailSerializer):
|
||||||
# 'wine_sub_region',
|
# 'wine_sub_region',
|
||||||
'wine_village',
|
'wine_village',
|
||||||
'state',
|
'state',
|
||||||
|
'site',
|
||||||
|
'product_type'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ProductTypeBackOfficeDetailSerializer(ProductTypeBaseSerializer):
|
class ProductTypeBackOfficeDetailSerializer(ProductTypeBaseSerializer):
|
||||||
"""Product type back-office detail serializer."""
|
"""Product type back-office detail serializer."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ class ProductBaseSerializer(serializers.ModelSerializer):
|
||||||
wine_colors = TagBaseSerializer(many=True, read_only=True)
|
wine_colors = TagBaseSerializer(many=True, read_only=True)
|
||||||
preview_image_url = serializers.URLField(allow_null=True,
|
preview_image_url = serializers.URLField(allow_null=True,
|
||||||
read_only=True)
|
read_only=True)
|
||||||
in_favorites = serializers.BooleanField(allow_null=True)
|
in_favorites = serializers.BooleanField(allow_null=True, read_only=True)
|
||||||
wine_origins = EstablishmentWineOriginBaseSerializer(many=True, read_only=True)
|
wine_origins = EstablishmentWineOriginBaseSerializer(many=True, read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
121
apps/product/tests.py
Normal file
121
apps/product/tests.py
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
from rest_framework import status
|
||||||
|
from account.models import User
|
||||||
|
from http.cookies import SimpleCookie
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
|
from translation.models import Language
|
||||||
|
from account.models import Role, UserRole
|
||||||
|
from location.models import Country, Address, City, Region
|
||||||
|
from main.models import SiteSettings
|
||||||
|
from product.models import Product, ProductType
|
||||||
|
|
||||||
|
class BaseTestCase(APITestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.username = 'sedragurda'
|
||||||
|
self.password = 'sedragurdaredips19'
|
||||||
|
self.email = 'sedragurda@desoz.com'
|
||||||
|
self.newsletter = True
|
||||||
|
self.user = User.objects.create_user(
|
||||||
|
username=self.username,
|
||||||
|
email=self.email,
|
||||||
|
password=self.password,
|
||||||
|
is_staff=True,
|
||||||
|
)
|
||||||
|
# get tokens
|
||||||
|
tokens = User.create_jwt_tokens(self.user)
|
||||||
|
self.client.cookies = SimpleCookie(
|
||||||
|
{'access_token': tokens.get('access_token'),
|
||||||
|
'refresh_token': tokens.get('refresh_token')})
|
||||||
|
|
||||||
|
|
||||||
|
self.lang = Language.objects.create(
|
||||||
|
title='Russia',
|
||||||
|
locale='ru-RU'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.country_ru = Country.objects.create(
|
||||||
|
name={'en-GB': 'Russian'},
|
||||||
|
code='RU',
|
||||||
|
)
|
||||||
|
|
||||||
|
self.region = Region.objects.create(name='Moscow area', code='01',
|
||||||
|
country=self.country_ru)
|
||||||
|
self.region.save()
|
||||||
|
|
||||||
|
self.city = City.objects.create(
|
||||||
|
name='Mosocow', code='01',
|
||||||
|
region=self.region,
|
||||||
|
country=self.country_ru)
|
||||||
|
self.city.save()
|
||||||
|
|
||||||
|
self.address = Address.objects.create(
|
||||||
|
city=self.city, street_name_1='Krasnaya',
|
||||||
|
number=2, postal_code='010100')
|
||||||
|
self.address.save()
|
||||||
|
|
||||||
|
self.site = SiteSettings.objects.create(
|
||||||
|
subdomain='ru',
|
||||||
|
country=self.country_ru
|
||||||
|
)
|
||||||
|
|
||||||
|
self.site.save()
|
||||||
|
|
||||||
|
self.role = Role.objects.create(role=Role.LIQUOR_REVIEWER,
|
||||||
|
site=self.site)
|
||||||
|
self.role.save()
|
||||||
|
|
||||||
|
self.user_role = UserRole.objects.create(
|
||||||
|
user=self.user, role=self.role)
|
||||||
|
|
||||||
|
self.user_role.save()
|
||||||
|
|
||||||
|
self.product_type = ProductType.objects.create(index_name=ProductType.LIQUOR)
|
||||||
|
self.product_type.save()
|
||||||
|
|
||||||
|
self.product = Product.objects.create(name='Product')
|
||||||
|
self.product.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LiquorReviewerTests(BaseTestCase):
|
||||||
|
def test_get(self):
|
||||||
|
self.product.product_type = self.product_type
|
||||||
|
self.product.save()
|
||||||
|
|
||||||
|
url = reverse("back:product:list-create")
|
||||||
|
response = self.client.get(url, format='json')
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
url = reverse("back:product:rud", kwargs={'pk': self.product.id})
|
||||||
|
response = self.client.get(url, format='json')
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
def test_post_patch_put_delete(self):
|
||||||
|
data_post = {
|
||||||
|
"slug": None,
|
||||||
|
"public_mark": None,
|
||||||
|
"vintage": None,
|
||||||
|
"average_price": None,
|
||||||
|
"description": None,
|
||||||
|
"available": False,
|
||||||
|
"establishment": None,
|
||||||
|
"wine_village": None,
|
||||||
|
"state": Product.PUBLISHED,
|
||||||
|
"site_id": self.site.id,
|
||||||
|
"product_type_id": self.product_type.id
|
||||||
|
}
|
||||||
|
url = reverse("back:product:list-create")
|
||||||
|
response = self.client.post(url, data=data_post, format='json')
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
|
||||||
|
data_patch = {
|
||||||
|
'name': 'Test product'
|
||||||
|
}
|
||||||
|
url = reverse("back:product:rud", kwargs={'pk': self.product.id})
|
||||||
|
response = self.client.patch(url, data=data_patch, format='json')
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -7,6 +7,7 @@ from product import serializers, models
|
||||||
from product.views import ProductBaseView
|
from product.views import ProductBaseView
|
||||||
from utils.serializers import ImageBaseSerializer
|
from utils.serializers import ImageBaseSerializer
|
||||||
from utils.views import CreateDestroyGalleryViewMixin
|
from utils.views import CreateDestroyGalleryViewMixin
|
||||||
|
from utils.permissions import IsLiquorReviewer, IsProductReviewer
|
||||||
|
|
||||||
|
|
||||||
class ProductBackOfficeMixinView(ProductBaseView):
|
class ProductBackOfficeMixinView(ProductBaseView):
|
||||||
|
|
@ -91,12 +92,14 @@ class ProductDetailBackOfficeView(ProductBackOfficeMixinView,
|
||||||
generics.RetrieveUpdateDestroyAPIView):
|
generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""Product back-office R/U/D view."""
|
"""Product back-office R/U/D view."""
|
||||||
serializer_class = serializers.ProductBackOfficeDetailSerializer
|
serializer_class = serializers.ProductBackOfficeDetailSerializer
|
||||||
|
permission_classes = [IsLiquorReviewer | IsProductReviewer]
|
||||||
|
|
||||||
|
|
||||||
class ProductListCreateBackOfficeView(BackOfficeListCreateMixin, ProductBackOfficeMixinView,
|
class ProductListCreateBackOfficeView(BackOfficeListCreateMixin, ProductBackOfficeMixinView,
|
||||||
generics.ListCreateAPIView):
|
generics.ListCreateAPIView):
|
||||||
"""Product back-office list-create view."""
|
"""Product back-office list-create view."""
|
||||||
serializer_class = serializers.ProductBackOfficeDetailSerializer
|
serializer_class = serializers.ProductBackOfficeDetailSerializer
|
||||||
|
permission_classes = [IsLiquorReviewer | IsProductReviewer]
|
||||||
|
|
||||||
|
|
||||||
class ProductTypeListCreateBackOfficeView(BackOfficeListCreateMixin,
|
class ProductTypeListCreateBackOfficeView(BackOfficeListCreateMixin,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ from authorization.models import JWTRefreshToken
|
||||||
from utils.tokens import GMRefreshToken
|
from utils.tokens import GMRefreshToken
|
||||||
from establishment.models import EstablishmentSubType
|
from establishment.models import EstablishmentSubType
|
||||||
from location.models import Address
|
from location.models import Address
|
||||||
|
from product.models import Product, ProductType
|
||||||
|
|
||||||
|
|
||||||
class IsAuthenticatedAndTokenIsValid(permissions.BasePermission):
|
class IsAuthenticatedAndTokenIsValid(permissions.BasePermission):
|
||||||
"""
|
"""
|
||||||
|
|
@ -81,32 +83,20 @@ class IsStandardUser(IsGuest):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
rules = [
|
|
||||||
super().has_permission(request, view)
|
|
||||||
]
|
|
||||||
|
|
||||||
# and request.user.email_confirmed,
|
rules = [super().has_permission(request, view),
|
||||||
if hasattr(request, 'user'):
|
|
||||||
rules = [
|
|
||||||
request.user.is_authenticated,
|
request.user.is_authenticated,
|
||||||
super().has_permission(request, view)
|
hasattr(request, 'user')
|
||||||
]
|
]
|
||||||
|
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
# Read permissions are allowed to any request
|
# Read permissions are allowed to any request
|
||||||
rules = [
|
|
||||||
super().has_object_permission(request, view, obj)
|
|
||||||
]
|
|
||||||
|
|
||||||
if hasattr(obj, 'user'):
|
rules = [super().has_object_permission(request, view, obj),
|
||||||
rules = [
|
request.user.is_authenticated,
|
||||||
obj.user == request.user
|
hasattr(request, 'user')
|
||||||
and obj.user.email_confirmed
|
|
||||||
and request.user.is_authenticated,
|
|
||||||
|
|
||||||
super().has_object_permission(request, view, obj)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
@ -408,7 +398,7 @@ class IsWineryReviewer(IsStandardUser):
|
||||||
|
|
||||||
est = EstablishmentSubType.objects.filter(establishment_type_id=request.data['type_id'])
|
est = EstablishmentSubType.objects.filter(establishment_type_id=request.data['type_id'])
|
||||||
if est.exists():
|
if est.exists():
|
||||||
role = Role.objects.filter(establishment_subtype_id__in=[type.id for type in est],
|
role = Role.objects.filter(establishment_subtype_id__in=[est_type.id for est_type in est],
|
||||||
role=Role.WINERY_REVIEWER,
|
role=Role.WINERY_REVIEWER,
|
||||||
country_id__in=[country.id for country in countries]) \
|
country_id__in=[country.id for country in countries]) \
|
||||||
.first()
|
.first()
|
||||||
|
|
@ -433,7 +423,7 @@ class IsWineryReviewer(IsStandardUser):
|
||||||
|
|
||||||
est = EstablishmentSubType.objects.filter(establishment_type_id=type_id)
|
est = EstablishmentSubType.objects.filter(establishment_type_id=type_id)
|
||||||
role = Role.objects.filter(role=Role.WINERY_REVIEWER,
|
role = Role.objects.filter(role=Role.WINERY_REVIEWER,
|
||||||
establishment_subtype_id__in=[id for type.id in est],
|
establishment_subtype_id__in=[est_type.id for est_type in est],
|
||||||
country_id=obj.country_id).first()
|
country_id=obj.country_id).first()
|
||||||
|
|
||||||
object_id: int
|
object_id: int
|
||||||
|
|
@ -449,3 +439,159 @@ class IsWineryReviewer(IsStandardUser):
|
||||||
super().has_object_permission(request, view, obj)
|
super().has_object_permission(request, view, obj)
|
||||||
]
|
]
|
||||||
return any(rules)
|
return any(rules)
|
||||||
|
|
||||||
|
|
||||||
|
class IsWineryReviewer(IsStandardUser):
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
rules = [
|
||||||
|
super().has_permission(request, view)
|
||||||
|
]
|
||||||
|
|
||||||
|
if 'type_id' in request.data and 'address_id' in request.data and request.user:
|
||||||
|
countries = Address.objects.filter(id=request.data['address_id'])
|
||||||
|
|
||||||
|
est = EstablishmentSubType.objects.filter(establishment_type_id=request.data['type_id'])
|
||||||
|
if est.exists():
|
||||||
|
role = Role.objects.filter(establishment_subtype_id__in=[est_type.id for est_type in est],
|
||||||
|
role=Role.WINERY_REVIEWER,
|
||||||
|
country_id__in=[country.id for country in countries]) \
|
||||||
|
.first()
|
||||||
|
|
||||||
|
rules.append(
|
||||||
|
UserRole.objects.filter(user=request.user, role=role).exists()
|
||||||
|
)
|
||||||
|
|
||||||
|
return any(rules)
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
rules = [
|
||||||
|
super().has_object_permission(request, view, obj)
|
||||||
|
]
|
||||||
|
|
||||||
|
if hasattr(obj, 'type_id') or hasattr(obj, 'establishment_type_id'):
|
||||||
|
type_id: int
|
||||||
|
if hasattr(obj, 'type_id'):
|
||||||
|
type_id = obj.type_id
|
||||||
|
else:
|
||||||
|
type_id = obj.establishment_type_id
|
||||||
|
|
||||||
|
est = EstablishmentSubType.objects.filter(establishment_type_id=type_id)
|
||||||
|
role = Role.objects.filter(role=Role.WINERY_REVIEWER,
|
||||||
|
establishment_subtype_id__in=[est_type.id for est_type in est],
|
||||||
|
country_id=obj.country_id).first()
|
||||||
|
|
||||||
|
object_id: int
|
||||||
|
if hasattr(obj, 'object_id'):
|
||||||
|
object_id = obj.object_id
|
||||||
|
else:
|
||||||
|
object_id = obj.establishment_id
|
||||||
|
|
||||||
|
rules = [
|
||||||
|
UserRole.objects.filter(user=request.user, role=role,
|
||||||
|
establishment_id=object_id
|
||||||
|
).exists(),
|
||||||
|
super().has_object_permission(request, view, obj)
|
||||||
|
]
|
||||||
|
return any(rules)
|
||||||
|
|
||||||
|
|
||||||
|
class IsProductReviewer(IsStandardUser):
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
rules = [
|
||||||
|
super().has_permission(request, view)
|
||||||
|
]
|
||||||
|
|
||||||
|
pk_object = None
|
||||||
|
roles = None
|
||||||
|
permission = False
|
||||||
|
|
||||||
|
if 'site_id' in request.data:
|
||||||
|
if request.data['site_id'] is not None:
|
||||||
|
roles = Role.objects.filter(role=Role.PRODUCT_REVIEWER,
|
||||||
|
site_id=request.data['site_id'])
|
||||||
|
|
||||||
|
if 'pk' in view.kwargs:
|
||||||
|
pk_object = view.kwargs['pk']
|
||||||
|
|
||||||
|
if pk_object is not None:
|
||||||
|
product = Product.objects.get(pk=pk_object)
|
||||||
|
if product.site_id is not None:
|
||||||
|
roles = Role.objects.filter(role=Role.PRODUCT_REVIEWER,
|
||||||
|
site_id=product.site_id)
|
||||||
|
|
||||||
|
if roles is not None:
|
||||||
|
permission = UserRole.objects.filter(user=request.user, role__in=[role for role in roles])\
|
||||||
|
.exists()
|
||||||
|
|
||||||
|
rules.append(permission)
|
||||||
|
return any(rules)
|
||||||
|
|
||||||
|
|
||||||
|
class IsLiquorReviewer(IsStandardUser):
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
rules = [
|
||||||
|
super().has_permission(request, view)
|
||||||
|
]
|
||||||
|
|
||||||
|
pk_object = None
|
||||||
|
roles = None
|
||||||
|
permission = False
|
||||||
|
|
||||||
|
if 'site_id' in request.data and 'product_type_id' in request.data:
|
||||||
|
if request.data['site_id'] is not None \
|
||||||
|
and request.data['product_type_id'] is not None:
|
||||||
|
|
||||||
|
product_types = ProductType.objects. \
|
||||||
|
filter(index_name=ProductType.LIQUOR,
|
||||||
|
id=request.data['product_type_id'])
|
||||||
|
|
||||||
|
if product_types.exists():
|
||||||
|
roles = Role.objects.filter(role=Role.LIQUOR_REVIEWER,
|
||||||
|
site_id=request.data['site_id'])
|
||||||
|
|
||||||
|
if 'pk' in view.kwargs:
|
||||||
|
pk_object = view.kwargs['pk']
|
||||||
|
|
||||||
|
if pk_object is not None:
|
||||||
|
product = Product.objects.get(pk=pk_object)
|
||||||
|
if product.site_id is not None \
|
||||||
|
and product.product_type_id is not None:
|
||||||
|
|
||||||
|
product_types = ProductType.objects. \
|
||||||
|
filter(index_name=ProductType.LIQUOR,
|
||||||
|
id=product.product_type_id)
|
||||||
|
|
||||||
|
if product_types.exists():
|
||||||
|
roles = Role.objects.filter(role=Role.LIQUOR_REVIEWER,
|
||||||
|
site_id=product.site_id)
|
||||||
|
|
||||||
|
if roles is not None:
|
||||||
|
permission = UserRole.objects.filter(user=request.user, role__in=[role for role in roles])\
|
||||||
|
.exists()
|
||||||
|
|
||||||
|
rules.append(permission)
|
||||||
|
return any(rules)
|
||||||
|
|
||||||
|
#
|
||||||
|
# def has_object_permission(self, request, view, obj):
|
||||||
|
# rules = [
|
||||||
|
# super().has_object_permission(request, view, obj)
|
||||||
|
# ]
|
||||||
|
# # pk_object = None
|
||||||
|
# # product = None
|
||||||
|
# # permission = False
|
||||||
|
# #
|
||||||
|
# # if 'pk' in view.kwargs:
|
||||||
|
# # pk_object = view.kwargs['pk']
|
||||||
|
# #
|
||||||
|
# # if pk_object is not None:
|
||||||
|
# # product = Product.objects.get(pk=pk_object)
|
||||||
|
# #
|
||||||
|
# # if product.sites.exists():
|
||||||
|
# # role = Role.objects.filter(role=Role.LIQUOR_REVIEWER, site__in=[site for site in product.sites])
|
||||||
|
# # permission = UserRole.objects.filter(user=request.user, role=role).exists()
|
||||||
|
# #
|
||||||
|
# # rules.append(permission)
|
||||||
|
# return any(rules)
|
||||||
|
|
@ -29,8 +29,7 @@ MEDIA_ROOT = os.path.join(PUBLIC_ROOT, MEDIA_LOCATION)
|
||||||
# SORL thumbnails
|
# SORL thumbnails
|
||||||
THUMBNAIL_DEBUG = True
|
THUMBNAIL_DEBUG = True
|
||||||
|
|
||||||
# ADDED TRANSFER APP
|
|
||||||
INSTALLED_APPS.append('transfer.apps.TransferConfig')
|
|
||||||
|
|
||||||
# DATABASES
|
# DATABASES
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user