239 lines
8.7 KiB
Python
239 lines
8.7 KiB
Python
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
|
|
amount = getattr(obj, 'special_discount_amount', None)
|
|
if amount is None:
|
|
# If it's an order item, check item_special_discount_amount property
|
|
amount = getattr(obj, 'item_special_discount_amount', 0)
|
|
if amount is None or amount == 0:
|
|
return None
|
|
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', 'is_paid']
|
|
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
|
|
|
|
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 OrderItemDetailSerializer(serializers.ModelSerializer):
|
|
product = serializers.SerializerMethodField()
|
|
price = serializers.SerializerMethodField()
|
|
final_price = serializers.SerializerMethodField()
|
|
discount_amount = serializers.SerializerMethodField()
|
|
special_discount = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = OrderItemModel
|
|
fields = [
|
|
'id', 'product', 'quantity', 'price', 'final_price',
|
|
'discount_amount', 'discount_percent', 'special_discount',
|
|
]
|
|
|
|
def get_product(self, obj):
|
|
return ProductVariantSerialzier(
|
|
instance=obj.product, context={'request': self.context.get('request')}
|
|
).data
|
|
|
|
def get_price(self, obj):
|
|
return f'{obj.total_price_before_discount():,.0f} تومانءءء'
|
|
|
|
def get_final_price(self, obj):
|
|
return f'{obj.price_after_special_discount():,.0f} تومانءءء'
|
|
|
|
def get_discount_amount(self, obj):
|
|
return f'{obj.total_product_discount_amount():,.0f} تومانءءء'
|
|
|
|
def get_special_discount(self, obj):
|
|
if obj.special_discount_amount:
|
|
return f'{obj.special_discount_amount:,.0f} تومانءءء'
|
|
return None
|
|
|
|
|
|
class OrderGetSerializer(serializers.ModelSerializer):
|
|
count = serializers.SerializerMethodField()
|
|
images = serializers.SerializerMethodField()
|
|
order_id = serializers.SerializerMethodField()
|
|
verbose_status = serializers.SerializerMethodField()
|
|
items = OrderItemDetailSerializer(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
|