from decimal import Decimal from django.conf import settings from product.models import Product from .models import Cart as CartModel, CartItem class Cart(object): def __init__(self, request): """ Initialize the cart. """ self.session = request.session self.user = request.user # Session cart initialization cart = self.session.get(settings.CART_SESSION_ID) if not cart: cart = self.session[settings.CART_SESSION_ID] = {} self.cart = cart def add(self, product, quantity=1, override_quantity=False): """ Add a product to the cart or update its quantity. """ if self.user.is_authenticated: self._add_db(product, quantity, override_quantity) else: self._add_session(product, quantity, override_quantity) def _add_session(self, product, quantity, override_quantity): product_id = str(product.id) if product_id not in self.cart: self.cart[product_id] = {'quantity': 0, 'price': str(product.price)} if override_quantity: self.cart[product_id]['quantity'] = quantity else: self.cart[product_id]['quantity'] += quantity if self.cart[product_id]['quantity'] <= 0: self.remove(product) else: self.save() def _add_db(self, product, quantity, override_quantity): cart, created = CartModel.objects.get_or_create(user=self.user) cart_item, item_created = CartItem.objects.get_or_create(cart=cart, product=product) if override_quantity: cart_item.quantity = quantity else: if not item_created: cart_item.quantity += quantity else: cart_item.quantity = quantity # Yeni oluşturulduysa zaten default 1 değil, gelen quantity olmalı if cart_item.quantity <= 0: cart_item.delete() else: cart_item.save() def save(self): # mark the session as "modified" to make sure it gets saved self.session.modified = True def remove(self, product): """ Remove a product from the cart. """ if self.user.is_authenticated: CartItem.objects.filter(cart__user=self.user, product=product).delete() else: product_id = str(product.id) if product_id in self.cart: del self.cart[product_id] self.save() def __iter__(self): """ Iterate over the items in the cart and get the products from the database. """ if self.user.is_authenticated: # DB'den oku cart, created = CartModel.objects.get_or_create(user=self.user) for item in cart.items.select_related('product').all(): yield { 'product': item.product, 'quantity': item.quantity, 'price': Decimal(item.product.price), 'total_price': Decimal(item.product.price) * item.quantity } else: # Session'dan oku product_ids = self.cart.keys() products = Product.objects.filter(id__in=product_ids) cart = self.cart.copy() for product in products: cart[str(product.id)]['product'] = product for item in cart.values(): item['price'] = Decimal(item['price']) item['total_price'] = item['price'] * item['quantity'] yield item def __len__(self): """ Count all items in the cart. """ if self.user.is_authenticated: cart, created = CartModel.objects.get_or_create(user=self.user) return sum(item.quantity for item in cart.items.all()) else: return sum(item['quantity'] for item in self.cart.values()) def get_total_price(self): if self.user.is_authenticated: cart, created = CartModel.objects.get_or_create(user=self.user) return sum(item.total_price for item in cart.items.all()) else: return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values()) def clear(self): if self.user.is_authenticated: cart, created = CartModel.objects.get_or_create(user=self.user) cart.items.all().delete() else: del self.session[settings.CART_SESSION_ID] self.save()