from django.conf import settings from rest_framework import serializers from .models import OrderItemModel, OrderModel, DiscountCode, Cart, CartItem from product.serializers import ProductVariantSerialzier, AttributeValueSerialzier, ProductImageSerailizer from account.serializers import UserAddressSerializer from product.models import ProductVariant class ProductVariantSerialzier(serializers.ModelSerializer): product_attributes = AttributeValueSerialzier(many=True) image = serializers.SerializerMethodField() discount_amount = serializers.SerializerMethodField() title = serializers.SerializerMethodField() price = serializers.SerializerMethodField() final_price = serializers.SerializerMethodField() category = serializers.SerializerMethodField() slug = serializers.CharField(source='product.slug') class Meta: model = ProductVariant fields = ['id', 'slug', 'title', 'product_attributes', 'in_stock', 'price', 'discount', 'color', 'image', 'discount_amount', 'category', 'final_price'] def get_discount_amount(self, obj): discount_amount = int(obj.price * (obj.discount / 100)) return f'{discount_amount:,.0f} تومان' def get_final_price(self, obj): final_price = obj.price - int(obj.price * (obj.discount / 100)) return f'{final_price:,.0f} تومان' def get_price(self, obj): return f'{obj.price:,.0f} تومان' def get_image(self, obj): return self.context.get('request').build_absolute_uri(obj.images.all().first().image.url) def get_title(self, obj): return obj.product.name def get_category(self, obj): return obj.product.category.name class DiscountCodeSerializer(serializers.ModelSerializer): class Meta: model = DiscountCode fields = ('code', 'percent') read_only_fields = ('percent',) class OrderItemSerailzier(serializers.ModelSerializer): product = serializers.SerializerMethodField() discount_amount = serializers.SerializerMethodField() price = serializers.SerializerMethodField() final_price = serializers.SerializerMethodField() discount = serializers.SerializerMethodField() special_discount_amount = serializers.SerializerMethodField() class Meta: model = CartItem exclude = ('cart',) read_only_fields = ('cart', 'product', 'discount_percent') def get_product(self, obj): return ProductVariantSerialzier(instance=obj.product_variant, context={'request': self.context.get('request')}).data def get_discount_amount(self, obj): return f'{obj.item_discount_amount:,.0f} تومان' def get_final_price(self, obj): return f'{obj.price_after_discount:,.0f} تومان' def get_price(self, obj): return f'{obj.price_before_discount:,.0f} تومان' def get_discount(self, obj): return obj.product_variant.discount def get_special_discount_amount(self, obj): # For cart items print('in here asdfasfd') amount = getattr(obj, 'special_discount_amount', None) print(amount) if amount is None: print('in here') # If it's an order item, check item_special_discount_amount property amount = getattr(obj, 'item_special_discount_amount', 0) if amount is None: amount = 0 print('in here ') return f'{int(amount):,.0f} تومان' class CartSerializer(serializers.ModelSerializer): items = OrderItemSerailzier(many=True) cart_total = serializers.SerializerMethodField() tax_amount = serializers.SerializerMethodField() final_price = serializers.SerializerMethodField() discount_code = serializers.SerializerMethodField() items_discount_amount = serializers.SerializerMethodField() special_discount_total = serializers.SerializerMethodField() special_discount_code = serializers.SerializerMethodField() address = UserAddressSerializer() class Meta: model = Cart fields = ['items_discount_amount', 'discount_code', 'items', 'cart_total', 'tax_amount', 'final_price', 'address', 'special_discount_total', 'special_discount_code'] def get_special_discount_code(self, obj): if obj.special_discount_code: return { 'code': f'{obj.special_discount_code.code}', 'user': f'{obj.special_discount_code.user.phone}' } else: return None def get_discount_code(self, obj): if obj.discount_code: return { 'code': f'{obj.discount_code.code}', 'percent': obj.discount_code.percent, 'amount': f'{obj.discount_code_amount:,.0f} تومان' } else: return None def get_tax_amount(self, obj): return f'{obj.tax_amount:,.0f} تومان' def get_cart_total(self, obj): return f'{obj.cart_total:,.0f} تومان' def get_items_discount_amount(self, obj): return f'{obj.items_discount_amount:,.0f} تومان' def get_final_price(self, obj): return f'{obj.final_price:,.0f} تومان' def get_special_discount_total(self, obj): # sum of special discounts on cart items total = obj.special_discount_total if hasattr( obj, 'special_discount_total') else 0 return f'{int(total):,.0f} تومان' class OrderListSerializer(serializers.ModelSerializer): count = serializers.SerializerMethodField() images = serializers.SerializerMethodField() verbose_status = serializers.SerializerMethodField() order_id = serializers.SerializerMethodField() class Meta: model = OrderModel fields = ['created_at', 'status', "images", "count", "id", 'final_price', 'order_id', 'verbose_status'] read_only_fields = ['count', 'images', 'order_id', 'verbose_status'] def get_verbose_status(self, obj): return obj.get_status_display() def get_count(self, obj): return obj.items.all().count() def get_order_id(self, obj): return obj.pk + 1000 def get_images(self, obj): image_list = [ self.context.get('request').build_absolute_uri(image.image.url) if (image := item.product.images.all().first()) else None for item in obj.items.all()[:3] ] return filter(lambda x: x is not None, image_list) class OrderGetSerializer(serializers.ModelSerializer): count = serializers.SerializerMethodField() images = serializers.SerializerMethodField() order_id = serializers.SerializerMethodField() verbose_status = serializers.SerializerMethodField() items = OrderItemSerailzier(many=True) address = UserAddressSerializer() discount_code = DiscountCodeSerializer() class Meta: model = OrderModel fields = ['created_at', 'status', "images", "count", "id", 'final_price', 'order_id', 'verbose_status', 'address', 'items', 'tax', 'cart_total', 'discount_code', 'discount_amount', 'special_discount_total'] def get_verbose_status(self, obj): return obj.get_status_display() def get_count(self, obj): return obj.items.all().count() def get_images(self, obj): image_list = [ self.context.get('request').build_absolute_uri(image.image.url) if (image := item.product.images.all().first()) else None for item in obj.items.all()[:3] ] return filter(lambda x: x is not None, image_list) def get_order_id(self, obj): return obj.id + 1000