from rest_framework import serializers from drf_spectacular.utils import extend_schema_field from .models import Category, Product, ProductImage, DiscountCode, Order, OrderItem, Carrier # NOTE: Carrier intentionally skipped per request (TODO below) class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = ["id", "name", "url", "parent", "description", "image"] class ProductImageSerializer(serializers.ModelSerializer): class Meta: model = ProductImage fields = ["id", "image", "alt_text", "is_main"] class ProductSerializer(serializers.ModelSerializer): images = ProductImageSerializer(many=True, read_only=True) available = serializers.BooleanField(read_only=True) class Meta: model = Product fields = [ "id","name","description","code","category","price","currency","url","stock","is_active","limited_to","default_carrier","available","images","created_at","updated_at" ] read_only_fields = ["created_at","updated_at","available"] class DiscountCodeSerializer(serializers.ModelSerializer): is_valid = serializers.SerializerMethodField() class Meta: model = DiscountCode fields = ["id","code","description","percent","amount","valid_from","valid_to","active","usage_limit","used_count","specific_products","specific_categories","is_valid"] read_only_fields = ["used_count","is_valid"] def get_is_valid(self, obj): return obj.is_valid() class OrderItemSerializer(serializers.ModelSerializer): product = serializers.PrimaryKeyRelatedField(queryset=Product.objects.all()) line_total = serializers.SerializerMethodField() class Meta: model = OrderItem fields = ["id","product","quantity","line_total"] read_only_fields = ["line_total"] def get_line_total(self, obj): # Uses existing model logic for discount via order context (kept minimal) # Since discount resolution logic is custom & currently incomplete, just returns base price * qty return obj.product.price * obj.quantity class OrderSerializer(serializers.ModelSerializer): items = OrderItemSerializer(many=True) total_price = serializers.DecimalField(max_digits=10, decimal_places=2, read_only=True) class Meta: model = Order fields = [ "id","user","status","total_price","currency","first_name","last_name","email","phone","address","city","postal_code","country","note","discount","items","created_at","updated_at" ] read_only_fields = ["total_price","created_at","updated_at"] def create(self, validated_data): items_data = validated_data.pop("items", []) order = Order.objects.create(**validated_data) for item in items_data: OrderItem.objects.create(order=order, **item) order.total_price = order.calculate_total_price() if hasattr(order, "calculate_total_price") else order.total_price order.save() return order def update(self, instance, validated_data): items_data = validated_data.pop("items", None) for attr, value in validated_data.items(): setattr(instance, attr, value) if items_data is not None: instance.items.all().delete() for item in items_data: OrderItem.objects.create(order=instance, **item) instance.total_price = instance.calculate_total_price() if hasattr(instance, "calculate_total_price") else instance.total_price instance.save() return instance # TODO: CarrierSerializer (Carrier API not requested yet)