from decimal import Decimal from typing import Any from django.core.exceptions import ValidationError from django.utils import formats from items.models import Item from orders.models import Cart, CartItem def format_currency(value: Decimal) -> str: return f"{formats.number_format(value, 2)} руб." def get_or_create_cart(user: Any) -> Cart: cart, _ = Cart.objects.get_or_create(user=user) return cart def get_user_cart_item_ids(user: Any) -> set[int]: if not getattr(user, "is_authenticated", False): return set() return set( CartItem.objects.filter(cart__user=user).values_list("item_id", flat=True) ) def get_user_cart(user: Any) -> Cart | None: if not getattr(user, "is_authenticated", False): return None return ( Cart.objects.filter(user=user) .prefetch_related("items__item__images") .select_related("user") .first() ) def add_item_to_cart(user: Any, item: Item, quantity: int = 1) -> tuple[CartItem, bool]: if quantity < 1: raise ValidationError("Количество товара должно быть не меньше 1.") if not item.is_available: raise ValidationError("Недоступный товар нельзя добавить в корзину.") cart = get_or_create_cart(user) cart_item, created = CartItem.objects.get_or_create( cart=cart, item=item, defaults={"quantity": quantity}, ) return cart_item, created def remove_item_from_cart(user: Any, item_id: int) -> bool: deleted, _ = CartItem.objects.filter(cart__user=user, item_id=item_id).delete() return bool(deleted) def update_cart_item_quantity(user: Any, item_id: int, quantity: int) -> CartItem: if quantity < 1: raise ValidationError("Количество товара должно быть не меньше 1.") cart_item = CartItem.objects.select_related("item").get(cart__user=user, item_id=item_id) cart_item.quantity = quantity cart_item.save(update_fields=["quantity", "updated_at"]) return cart_item