Compare commits
6 Commits
cfe2f68305
...
ca08955b38
| Author | SHA1 | Date | |
|---|---|---|---|
| ca08955b38 | |||
| a9c7e15e02 | |||
| 433f1ff180 | |||
| 72ade66fe1 | |||
| bae34e02c2 | |||
| d5d16d7cc8 |
|
|
@ -26,6 +26,12 @@ class UserSerializer(serializers.ModelSerializer):
|
|||
return obj.invited_users_with_orders.count()
|
||||
|
||||
|
||||
class UserSimpleSerializer(UserSerializer):
|
||||
class Meta:
|
||||
model = UserSerializer.Meta.model
|
||||
fields = ('id', 'email', 'phone', 'role', 'name', 'lastname', 'surname')
|
||||
|
||||
|
||||
def non_zero_validator(value):
|
||||
if value == 0:
|
||||
raise serializers.ValidationError("Value cannot be zero")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from functools import reduce
|
||||
|
||||
from django_filters import DateFromToRangeFilter as _DateFromToRangeFilter
|
||||
from rest_framework.fields import DecimalField
|
||||
|
||||
|
||||
|
|
@ -11,3 +12,11 @@ class PriceField(DecimalField):
|
|||
def deep_get(dictionary, *keys, default=None):
|
||||
"""Get value from a nested dictionary (JSON)"""
|
||||
return reduce(lambda d, key: d.get(key, None) if isinstance(d, dict) else default, keys, dictionary)
|
||||
|
||||
|
||||
class DateFromToRangeFilter(_DateFromToRangeFilter):
|
||||
""" DateFromToRangeFilter with replaced after/before suffixes to from/to """
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.field.widget.suffixes = ['from', 'to']
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from django_filters import rest_framework as filters
|
||||
|
||||
from poizonstore.utils import DateFromToRangeFilter
|
||||
from .models import Checklist, Gift
|
||||
|
||||
|
||||
|
|
@ -18,9 +19,12 @@ class ChecklistFilter(filters.FilterSet):
|
|||
status = filters.MultipleChoiceFilter(choices=Checklist.Status.CHOICES)
|
||||
delivery_code = filters.CharFilter(method='filter_delivery_code')
|
||||
|
||||
created_at = DateFromToRangeFilter()
|
||||
status_updated_at = DateFromToRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Checklist
|
||||
fields = ('status', 'delivery_code')
|
||||
fields = ('status', 'delivery_code', 'created_at', 'status_updated_at')
|
||||
|
||||
def filter_delivery_code(self, queryset, name, value):
|
||||
return queryset.filter(poizon_tracking__iendswith=value)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from drf_extra_fields.fields import Base64ImageField
|
|||
from rest_framework import serializers
|
||||
|
||||
from bonus_program.models import BonusProgram
|
||||
from account.serializers import UserSerializer
|
||||
from account.serializers import UserSimpleSerializer
|
||||
from utils.exceptions import CRMException
|
||||
from store.models import Checklist, Category, PaymentMethod, Promocode, Image, Gift
|
||||
from store.utils import get_primary_key_related_model
|
||||
|
|
@ -94,7 +94,7 @@ class ChecklistSerializer(serializers.ModelSerializer):
|
|||
|
||||
commission_rub = PriceField(read_only=True)
|
||||
|
||||
customer = get_primary_key_related_model(UserSerializer, required=False, allow_null=True)
|
||||
customer = get_primary_key_related_model(UserSimpleSerializer, required=False, allow_null=True)
|
||||
|
||||
receiver_name = serializers.CharField(required=False, allow_null=True)
|
||||
receiver_phone = serializers.CharField(required=False, allow_null=True)
|
||||
|
|
@ -193,6 +193,17 @@ class ChecklistSerializer(serializers.ModelSerializer):
|
|||
)
|
||||
|
||||
|
||||
class ChecklistListSerializer(ChecklistSerializer):
|
||||
class Meta:
|
||||
model = ChecklistSerializer.Meta.model
|
||||
fields = ('id', 'status',
|
||||
'category', 'brand', 'model', 'size', 'preview_image_url',
|
||||
'price_yuan', 'price_rub', 'full_price', 'real_price',
|
||||
'comment',
|
||||
'poizon_tracking', 'cdek_tracking', 'delivery', 'delivery_display',
|
||||
'created_at', 'status_updated_at')
|
||||
|
||||
|
||||
class ClientChecklistSerializerMixin:
|
||||
def validate(self, attrs):
|
||||
gift = attrs.get('gift')
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@ from rest_framework.response import Response
|
|||
|
||||
from external_api.cdek import CDEKClient, CDEKWebhookTypes, CDEK_STATUS_TO_ORDER_STATUS
|
||||
from external_api.poizon import PoizonClient
|
||||
from utils.exceptions import CRMException
|
||||
from utils.exceptions import CRMException, Forbidden
|
||||
from store.filters import GiftFilter, ChecklistFilter
|
||||
from store.models import Checklist, Category, PaymentMethod, Promocode, Gift
|
||||
from core.models import GlobalSettings
|
||||
from store.serializers import (ChecklistSerializer, CategorySerializer, CategoryFullSerializer,
|
||||
PaymentMethodSerializer, PromocodeSerializer, ClientUpdateChecklistSerializer,
|
||||
GiftSerializer, ClientCreateChecklistSerializer)
|
||||
GiftSerializer, ClientCreateChecklistSerializer, ChecklistListSerializer)
|
||||
from account.permissions import ReadOnly, IsManager, IsAdmin
|
||||
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ class ChecklistAPI(viewsets.ModelViewSet):
|
|||
super().permission_denied(request, **kwargs)
|
||||
|
||||
def get_serializer_class(self):
|
||||
# Managers have a full set of fields
|
||||
# Managers have a full set of fields for editing
|
||||
if getattr(self.request.user, 'is_manager', False) or self.action == 'retrieve':
|
||||
return ChecklistSerializer
|
||||
|
||||
|
|
@ -75,15 +75,17 @@ class ChecklistAPI(viewsets.ModelViewSet):
|
|||
elif self.action in ['update', 'partial_update', 'destroy']:
|
||||
return ClientUpdateChecklistSerializer
|
||||
|
||||
# Simplified list serializer
|
||||
elif self.action == "list":
|
||||
return ChecklistListSerializer
|
||||
|
||||
# Fallback to error
|
||||
self.permission_denied(self.request, **self.kwargs)
|
||||
|
||||
def get_permissions(self):
|
||||
if self.action in ['list', 'update', 'partial_update']:
|
||||
self.permission_classes = [IsManager]
|
||||
elif self.action == 'retrieve':
|
||||
if self.action == 'retrieve':
|
||||
self.permission_classes = [AllowAny]
|
||||
elif self.action in ['create', 'destroy']:
|
||||
elif self.action in ['create', 'list', 'update', 'partial_update', 'destroy']:
|
||||
self.permission_classes = [IsAuthenticated]
|
||||
|
||||
return super().get_permissions()
|
||||
|
|
@ -92,15 +94,21 @@ class ChecklistAPI(viewsets.ModelViewSet):
|
|||
# Non-managers can cancel orders only in certain statuses
|
||||
if (not getattr(self.request.user, 'is_manager', False)
|
||||
and obj.status not in Checklist.Status.CANCELLABLE_ORDER_STATUSES):
|
||||
raise CRMException("Can't delete the order")
|
||||
raise Forbidden("Can't delete the order")
|
||||
|
||||
obj.cancel()
|
||||
|
||||
def get_queryset(self):
|
||||
return Checklist.objects.with_base_related() \
|
||||
qs = Checklist.objects.with_base_related() \
|
||||
.annotate_bonus_used() \
|
||||
.default_ordering()
|
||||
|
||||
# Non-managers can list only their own orders
|
||||
if not getattr(self.request.user, 'is_manager', False):
|
||||
qs = qs.filter(customer_id=self.request.user.id)
|
||||
|
||||
return qs
|
||||
|
||||
def get_object(self):
|
||||
obj: Checklist = super().get_object()
|
||||
|
||||
|
|
@ -126,9 +134,10 @@ class CategoryAPI(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.Updat
|
|||
|
||||
class PaymentMethodsAPI(mixins.ListModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
|
||||
serializer_class = PaymentMethodSerializer
|
||||
permission_classes = [IsManager | ReadOnly]
|
||||
permission_classes = [IsAdmin | ReadOnly]
|
||||
lookup_field = 'slug'
|
||||
queryset = PaymentMethod.objects.all()
|
||||
pagination_class = None
|
||||
|
||||
|
||||
class PromoCodeAPI(viewsets.ModelViewSet):
|
||||
|
|
|
|||
|
|
@ -12,4 +12,7 @@ class CRMException(APIException):
|
|||
self.detail = {'error': detail}
|
||||
|
||||
|
||||
class Forbidden(CRMException):
|
||||
status_code = status.HTTP_403_FORBIDDEN
|
||||
|
||||
# TODO: exceptions with a same template: ok / error_code / error_message
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user