from drf_extra_fields.fields import Base64ImageField from rest_framework import serializers from store.models import User, Checklist, GlobalSettings, Category, PaymentMethod, Promocode, Image 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 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) 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', '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'}) class GlobalSettingsSerializer(serializers.ModelSerializer): currency = serializers.DecimalField(source='yuan_rate', 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', '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')