<commit_before># -*- coding: utf-8 -*-
from decimal import Decimal
from django.contrib.auth.models import User
from django.db import models
from shop.cart.modifiers_pool import cart_modifiers_pool
from shop.models.productmodel import Product

class Cart(models.Model):
    """
    This should be a rather simple list of items. Ideally it should be bound to
    a session and not to a User is we want to let people buy from our shop 
    without having to register with us.
    """
    # If the user is null, that means this is used for a session
    user = models.OneToOneField(User, null=True, blank=True)
    
    date_created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)
    
    class Meta:
        app_label = 'shop'
    
    def __init__(self, *args, **kwargs):
        super(Cart, self).__init__(*args,**kwargs)
        # That will hold things like tax totals or total discount
        self.subtotal_price = Decimal('0.0') 
        self.total_price = Decimal('0.0')
        self.extra_price_fields = [] # List of tuples (label, value) 
    
    def add_product(self,product, quantity=1):
        """
        Adds a (new) product to the cart
        """
        # Let's see if we already have an Item with the same product ID
        if CartItem.objects.filter(cart=self).filter(product=product).exists():
            cart_item = CartItem.objects.filter(cart=self).filter(product=product)[0]
            cart_item.quantity = cart_item.quantity + int(quantity)
            cart_item.save()
        else:
            cart_item = CartItem.objects.create(cart=self,quantity=quantity,product=product)
            cart_item.save()
            
        self.save() # to get the last updated timestamp
        
    def update_quantity(self, cart_item_id, quantity):
        """
        Updates the quantity for given cart item or deletes it if its quantity 
        reaches `0`
        """
        cart_item = self.items.get(pk=cart_item_id)
        if quantity == 0:
            cart_item.delete()
        else:
            cart_item.quantity = quantity
            cart_item.save()
        self.save()
    
    def delete_item(self, cart_item_id):
        """
        A simple convenience method to delete one of the cart's items. This
        allows to implicitely check for "access rights" since we insure the cartitem
        is actually in the user's cart<commit_msg>Added an option to specify whether to merge CartItem on add or to let them be another CartItem (should be helpful to people "struggling" with product variations).<commit_after># -*- coding: utf-8 -*-
from decimal import Decimal
from django.contrib.auth.models import User
from django.db import models
from shop.cart.modifiers_pool import cart_modifiers_pool
from shop.models.productmodel import Product

class Cart(models.Model):
    """
    This should be a rather simple list of items. Ideally it should be bound to
    a session and not to a User is we want to let people buy from our shop 
    without having to register with us.
    """
    # If the user is null, that means this is used for a session
    user = models.OneToOneField(User, null=True, blank=True)
    
    date_created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)
    
    class Meta:
        app_label = 'shop'
    
    def __init__(self, *args, **kwargs):
        super(Cart, self).__init__(*args,**kwargs)
        # That will hold things like tax totals or total discount
        self.subtotal_price = Decimal('0.0') 
        self.total_price = Decimal('0.0')
        self.extra_price_fields = [] # List of tuples (label, value) 
    
    def add_product(self, product, quantity=1, merge=True):
        """
        Adds a (new) product to the cart.
        The last parameter to this method, `merge`, controls wheter we should
        merge the added CartItem with another already existing sharing the same
        product_id.

        Example with merge = True:
        >>> self.items[0] = CartItem.objects.create(..., product=MyProduct())
        >>> self.add_product(MyProduct())
        >>> self.items[0].quantity
        2

        Example with merge=False:
        >>> self.items[0] = CartItem.objects.create(..., product=MyProduct())
        >>> self.add_product(MyProduct())
        >>> self.items[0].quantity
        1
        >>> self.items[1].quantity
        1

        This is useful when you have products with variations (for example),
        and you don't want to have your products merge (to loose their specific
        variations, for example).
        """
        item = CartItem.objects.filter(cart=self).filter(product=product)
        # Let's see if we already have an Item with the same product ID
        if item.exists() and merge:
            cart_item = item[0]
            cart_item.quantity = cart_item.quantity + int(quantity)
            cart_item.save()
        else:
            cart_item = CartItem.objects.create(cart=self,quantity=quantity,product=product)
            cart_item.save()
            
        self.save() # to get the last updated timestamp
        
    def update_quantity(self, cart_item_id, quantity):
        """
        Updates the quantity for given cart item or deletes it if its quantity 
        reaches `0`
        """
        cart_item = self.items.get(pk=cart_item_id)
        if quantity == 0:
            cart_item.delete()
        else:
            cart_item.quantity = quantity
            cart_item.save()
        self.save()
    
    def delete_item(self, cart_item_id):
        """
        A simple convenience method to delete one of the cart's items. This
        allows to implicitely check for "access rights" since we insure the cartitem
        is actually in the user's cart
{'fraction_non_alphanumeric': 0.08826064471642821, 'fraction_numerical': 0.004481985864506119, 'mean_word_length': 2.4433234421364984, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1326101', 'n_tokens_mistral': 1614, 'n_tokens_neox': 1573, 'n_words': 540}