""" Order serializer """ # import decimal from django.db.models import Q from django.utils.translation import gettext as _ from rest_framework import serializers from rest_framework.exceptions import PermissionDenied from core.apps.eggs import models from core.apps.eggs.models import Market, History, Notification from core.apps.eggs.serializers import courier, location, market from core.apps.eggs.serializers.order_item import OrderItemsSerializer from core.http.models import User from core.http.serializers import user class OrderCourierSerializer(serializers.ModelSerializer): user_id = user.UserSerializer() class Meta: model = models.Courier fields = ( "id", "user_id", ) class OrderSerializer(serializers.ModelSerializer): market = market.MarketSerializer(read_only=True, source="market_id") location = location.LocationSerializer( read_only=True, source="location_id" ) courier = courier.CourierSerializer(read_only=True, source="courier_id") order_items = OrderItemsSerializer(many=True, read_only=True) class Meta: model = models.Order fields = ( "id", "courier", "market", "location", "price", "price_paid", "debt", "status", "comment", "data", "count", "order_items", ) def to_representation(self, instance): representation = super().to_representation(instance) for field in ["price", "price_paid", "debt"]: try: representation[field] = str( round(float(representation[field]), 2) ) except (TypeError, ValueError): representation[field] = "Invalid value" return representation class OrderCreateSerializer(serializers.ModelSerializer): location = location.LocationSerializer(source="location_id", required=True) market = market.MarketSerializer(source="market_id", read_only=True) order_items = OrderItemsSerializer(many=True, required=False) class Meta: model = models.Order fields = ( "id", "market_id", "market", "comment", "price", "price_paid", "debt", "location", "status", "count", "order_items", ) def validate_price(self, value): try: return round(float(value), 2) except (TypeError, ValueError): raise serializers.ValidationError("Invalid price value.") def create(self, validated_data): order_items_data = validated_data.pop("order_items", []) location_data = validated_data.pop("location_id", None) request = self.context.get("request") if request and request.user.role == "market": try: market_instance = Market.objects.get(user_id=request.user.id) validated_data["market_id"] = market_instance except Market.DoesNotExist: raise PermissionDenied( "Bu foydalanuvchi uchun Market mavjud emas" ) if request and request.user.role == "courier": courier_instance = models.Courier.objects.get( user_id=request.user.id ) validated_data["courier_id"] = courier_instance if location_data: location = models.Location.objects.create(**location_data) validated_data["location_id"] = location # validated_data["price"] = self.validate_price( # validated_data.get("price", 0.00) # ) # validated_data["price_paid"] = self.validate_price( # validated_data.get("price_paid", 0.00) # ) # validated_data["debt"] = self.validate_price( # validated_data.get("debt", 0.00) # ) order_pk = super().create(validated_data).pk order = models.Order.objects.get(pk=order_pk) for order_item_data in order_items_data: models.OrderItems.objects.create(order_id=order, **order_item_data) created_who = "" if request: if request.user.role == "market" and order.market_id is not None: created_who = f"{order.market_id.user_id.first_name} {order.market_id.user_id.last_name}" elif ( request.user.role == "courier" and order.courier_id is not None ): created_who = f"{order.courier_id.user_id.first_name} {order.courier_id.user_id.last_name}" elif request.user.role == "admin": created_who = ( f"{request.user.first_name} {request.user.last_name}" ) History.objects.create( content_object=order, action="order_created", created_who=created_who, user_id=request.user, created_by=order.market_id.name, comment=order.comment, reason=_(f"Buyurtma: {order.price}"), avatar=( order.market_id.avatar if order.market_id.avatar else None ), ) notification_user = User.objects.filter( Q(role="admin") | Q(role="courier") ) for user in notification_user: Notification.objects.create( user=user, title=f"Yangi buyurtma: {order.price}", body=f"Yangi buyurtma: {order.market_id.name} {order.price}", ) return order def to_representation(self, instance): serializer = OrderSerializer(instance) return serializer.data def update(self, instance, validated_data): order_items_data = validated_data.pop("order_items", []) location_data = validated_data.pop("location_id", None) request = self.context.get("request") if request and request.user.role == "courier": courier_instance = models.Courier.objects.get( user_id=request.user.id ) instance.courier_id = courier_instance for attr, value in validated_data.items(): if attr in ["price", "price_paid", "debt"]: value = self.validate_price(value) setattr(instance, attr, value) instance.save() for order_item_data in order_items_data: models.OrderItems.objects.update_or_create( order_id=instance, defaults=order_item_data ) if location_data: location, created = models.Location.objects.update_or_create( id=instance.location_id.id if instance.location_id else None, defaults=location_data, ) instance.location_id = location instance.save() return instance