import logging from decimal import Decimal from django.conf import settings from core.models import Product, OrderLine from .payments import CreateOrder logger = logging.getLogger(__name__) class Cart: def __init__(self, request): self.session = request.session 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, roast='', update_quantity=False): product_id = str(product.id) if product_id not in self.cart: self.cart[product_id] = { 'quantity': 0, 'roast': roast, 'price': str(product.price) } elif product_id in self.cart: self.cart[product_id].update({ 'roast': roast, }) if update_quantity: self.cart[product_id]['quantity'] = quantity else: self.cart[product_id]['quantity'] += quantity self.save() def save(self): self.session[settings.CART_SESSION_ID] = self.cart self.session.modified = True logger.info(f'\nCart:\n{self.cart}\n') def remove(self, product): product_id = str(product.id) if product_id in self.cart: del self.cart[product_id] self.save() def __iter__(self): product_ids = self.cart.keys() products = Product.objects.filter(id__in=product_ids) for product in products: self.cart[str(product.id)]['product'] = product for item in self.cart.values(): item['price'] = Decimal(item['price']) item['total_price'] = item['price'] * item['quantity'] yield item def __len__(self): return sum(item['quantity'] for item in self.cart.values()) def get_total_price(self): return sum(Decimal(item['price']) * item['quantity'] for item in self.cart.values()) def clear(self): del self.session[settings.CART_SESSION_ID] self.session.modified = True def build_order_params(self): return \ { 'items': self, 'total_price': f'{self.get_total_price()}', 'item_total': f'{self.get_total_price()}', 'shipping_price': '0', 'tax_total': '0', 'shipping_method': 'US POSTAL SERVICE', 'shipping_address': self.build_shipping_address(self.session.get('shipping_address')), } def create_order(self): params = self.build_order_params() logger.info(f'\nParams: {params}\n') response = CreateOrder().create_order(params, debug=True) return response def build_bulk_list(self, order): bulk_list = [OrderLine( order=order, product=item['product'], customer_note=item['roast'], unit_price=item['price'], quantity=item['quantity'], tax_rate=2, ) for item in self] return bulk_list def build_shipping_address(self, address): return \ { 'address_line_1': f'{address["street_address_1"]}', 'address_line_2': f'{address["street_address_2"]}', 'admin_area_2': f'{address["city"]}', 'admin_area_1': f'{address["state"]}', 'postal_code': f'{address["postal_code"]}', 'country_code': 'US' } # @property # def coupon(self): # if self.coupon_id: # return Coupon.objects.get(id=self.coupon_id) # return None # def get_discount(self): # if self.coupon: # return (self.coupon.discount / Decimal('100')) * self.get_total_price() # return Decimal('0') # def get_total_price_after_discount(self): # return self.get_total_price() - self.get_discount()