kwork-poizonstore/store/serializers.py
phzhik ab9db45b2b + CurrencyAPIClient for fresh CNY rate
+ yuan_rate_last_updated, yuan_rate_commission fields in GlobalSettings
2023-11-23 02:16:53 +04:00

234 lines
9.9 KiB
Python

from drf_extra_fields.fields import Base64ImageField
from rest_framework import serializers
from store.exceptions import CRMException
from store.models import User, Checklist, GlobalSettings, Category, PaymentMethod, Promocode, Image, Gift
from store.utils import get_primary_key_related_model
class UserSerializer(serializers.ModelSerializer):
login = serializers.CharField(source='email', required=False)
job = serializers.CharField(source='job_title', required=False)
name = serializers.CharField(source='first_name', required=False)
lastname = serializers.CharField(source='middle_name', required=False)
surname = serializers.CharField(source='last_name', required=False)
class Meta:
model = User
fields = ('id', 'login', 'job', 'name', 'lastname', 'surname',)
class ImageSerializer(serializers.ModelSerializer):
image = Base64ImageField()
class Meta:
model = Image
fields = ('image',)
class ImageListSerializer(serializers.ListSerializer):
child = ImageSerializer()
def to_internal_value(self, data):
if isinstance(data, list):
data = [{"image": x} for x in data]
return super().to_internal_value(data)
def to_representation(self, data):
images = super().to_representation(data)
return [image['image'] for image in images]
class CategoryChecklistSerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name')
class CategorySerializer(serializers.ModelSerializer):
chinarush = serializers.DecimalField(source='delivery_price_CN_RU', max_digits=10, decimal_places=2)
class Meta:
model = Category
fields = ('id', 'name', 'chinarush', 'commission')
class CategoryFullSerializer(CategorySerializer):
children = serializers.SerializerMethodField()
def get_children(self, obj):
return CategoryFullSerializer(obj.get_children(), many=True).data
class Meta:
model = CategorySerializer.Meta.model
fields = CategorySerializer.Meta.fields + ('children',)
class GiftSerializer(serializers.ModelSerializer):
image = Base64ImageField(required=False, allow_null=True)
class Meta:
model = Gift
fields = ('id', 'name', 'image', 'min_price')
class ChecklistSerializer(serializers.ModelSerializer):
id = serializers.CharField(read_only=True)
managerid = serializers.PrimaryKeyRelatedField(source='manager_id', read_only=True, allow_null=True)
link = serializers.URLField(source='product_link', required=False)
category = get_primary_key_related_model(CategoryChecklistSerializer, required=False, allow_null=True)
size = serializers.CharField(required=False, allow_null=True)
image = ImageListSerializer(source='main_images', required=False)
previewimage = serializers.ImageField(source='preview_image_url', read_only=True)
promo = serializers.SlugRelatedField(source='promocode', slug_field='name',
queryset=Promocode.objects.active(), required=False, allow_null=True)
gift = get_primary_key_related_model(GiftSerializer, required=False, allow_null=True)
currency = serializers.DecimalField(source='yuan_rate', read_only=True, max_digits=10, decimal_places=2)
curencycurency2 = serializers.DecimalField(source='price_yuan', required=False, max_digits=10, decimal_places=2)
currency3 = serializers.IntegerField(source='price_rub', read_only=True)
chinadelivery = serializers.DecimalField(source='delivery_price_CN', read_only=True, max_digits=10, decimal_places=2)
chinadelivery2 = serializers.DecimalField(source='delivery_price_CN_RU', read_only=True,
max_digits=10, decimal_places=2)
fullprice = serializers.IntegerField(source='full_price', read_only=True)
realprice = serializers.DecimalField(source='real_price', required=False, allow_null=True, max_digits=10,
decimal_places=2)
commission = serializers.DecimalField(source='commission_rub', read_only=True, max_digits=10, decimal_places=2)
buyername = serializers.CharField(source='buyer_name', required=False, allow_null=True)
buyerphone = serializers.CharField(source='buyer_phone', required=False, allow_null=True)
tg = serializers.CharField(source='buyer_telegram', required=False, allow_null=True)
receivername = serializers.CharField(source='receiver_name', required=False, allow_null=True)
reveiverphone = serializers.CharField(source='receiver_phone', required=False, allow_null=True)
split = serializers.BooleanField(source='is_split_payment', required=False)
paymenttype = serializers.SlugRelatedField(source='payment_method', slug_field='slug',
queryset=PaymentMethod.objects.all(),
required=False, allow_null=True)
paymentprovement = Base64ImageField(source='payment_proof', required=False, allow_null=True)
split_payment_proof = Base64ImageField(required=False, allow_null=True)
checkphoto = Base64ImageField(source='receipt', required=False, allow_null=True)
trackid = serializers.CharField(source='poizon_tracking', required=False, allow_null=True)
cdek_tracking = serializers.CharField(required=False, allow_null=True)
delivery = serializers.ChoiceField(choices=Checklist.DeliveryType.CHOICES, required=False, allow_null=True)
delivery_display = serializers.CharField(source='get_delivery_display', read_only=True)
startDate = serializers.DateTimeField(source='created_at', read_only=True)
currentDate = serializers.DateTimeField(source='status_updated_at', read_only=True)
def _collect_images_by_fields(self, validated_data):
images = {}
for k in ('main_images',):
if k in validated_data:
images[k] = validated_data.pop(k)
return images
def _create_main_images(self, instance, images):
if images is None:
return
img_objs = [Image(image=img['image'], type=Image.DEFAULT) for img in images]
img_objs = Image.objects.bulk_create(img_objs)
instance.images.set(img_objs)
instance.generate_preview(next(iter(img_objs), None))
def create(self, validated_data):
images = self._collect_images_by_fields(validated_data)
instance = super().create(validated_data)
self._create_main_images(instance, images.get('main_images'))
return instance
def update(self, instance, validated_data):
images = self._collect_images_by_fields(validated_data)
# Perform update
instance: Checklist = super().update(instance, validated_data)
self._create_main_images(instance, images.get('main_images'))
# Invalidate prefetched images
delattr(instance, '_images')
if instance.status == Checklist.Status.NEW:
has_payment_info = instance.payment_proof is not None and instance.payment_method is not None
if has_payment_info:
instance.status = Checklist.Status.PAYMENT
instance.save()
return instance
@staticmethod
def get_image(obj: Checklist):
return obj.images.all()
class Meta:
model = Checklist
fields = ('id', 'status', 'managerid', 'link',
'category',
'brand', 'model', 'size',
'image',
'previewimage',
'currency', 'curencycurency2', 'currency3', 'chinadelivery', 'chinadelivery2', 'commission',
'promo', 'gift',
'comment',
'fullprice', 'realprice',
'buyername', 'buyerphone', 'tg',
'receivername', 'reveiverphone',
'split', 'paymenttype', 'paymentprovement', 'split_payment_proof', 'split_accepted', 'checkphoto',
'trackid', 'cdek_tracking', 'cdek_barcode_pdf', 'delivery', 'delivery_display',
'startDate', 'currentDate', 'buy_time_remaining'
)
class AnonymousUserChecklistSerializer(ChecklistSerializer):
class Meta:
model = ChecklistSerializer.Meta.model
fields = ChecklistSerializer.Meta.fields
read_only_fields = tuple(set(ChecklistSerializer.Meta.fields) -
{'paymentprovement', 'paymenttype',
'buyername', 'buyerphone',
'delivery',
'recievername', 'recieverphone', 'tg',
'gift', 'cdek_barcode_pdf'})
def validate(self, attrs):
gift = attrs.get('gift')
if gift is not None and self.instance.price_yuan < gift.min_price:
raise CRMException("Can't add gift: price of order < min_price of gift")
return attrs
class GlobalSettingsSerializer(serializers.ModelSerializer):
currency = serializers.DecimalField(source='get_yuan_rate', read_only=True, max_digits=10, decimal_places=2)
chinadelivery = serializers.DecimalField(source='delivery_price_CN', max_digits=10, decimal_places=2)
commission = serializers.DecimalField(source='commission_rub', max_digits=10, decimal_places=2)
pickup = serializers.CharField(source='pickup_address')
class Meta:
model = GlobalSettings
fields = ('currency', 'yuan_rate_commission', 'commission', 'chinadelivery', 'pickup', 'time_to_buy')
class PaymentMethodSerializer(serializers.ModelSerializer):
type = serializers.CharField(source='slug')
class Meta:
model = PaymentMethod
fields = ('type', 'name', 'requisites', 'cardnumber')
class PromocodeSerializer(serializers.ModelSerializer):
freedelivery = serializers.BooleanField(source='free_delivery')
nocomission = serializers.BooleanField(source='no_comission')
class Meta:
model = Promocode
fields = ('id', 'name', 'discount', 'freedelivery', 'nocomission', 'is_active')