# -*- coding: utf-8 -*-
""" 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
# That will hold things like tax totals or total discount
""" Adds a (new) product to the cart.
The parameter `merge`, controls wheter we should merge the added CartItem with another already existing sharing the same product_id. 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).
A drawback is, that generally setting `merge` to ``False`` for products with variations can be a problem if users can buy thousands of products at a time (that would mean we would create thousands of CartItems as well which all have the same variation).
The parameter `queryset` can be used to override the standard queryset that is being used to find the CartItem that should be merged into. If you use variations, just finding the first CartItem that belongs to this cart and the given product is not sufficient. You will want to find the CartItem that already has the same variations that the user chose for this request.
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 """ # Let's see if we already have an Item with the same product ID else: cart=self, quantity=quantity, product=product)
""" Updates the quantity for given cart item or deletes it if its quantity reaches `0` """ else:
""" 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 """
""" This should be called whenever anything is changed in the cart (added or removed) It will loop on all line items in the cart, and call all the price modifiers on each row. After doing this, it will compute and update the order's total and subtotal fields, along with any payment field added along the way by modifiers.
Note that theses added fields are not stored - we actually want to reflect rebate and tax changes on the *cart* items, but we don't want that for the order items (since they are legally binding after the "purchase" button was pressed) """
# Now we have to iterate over the registered modifiers again (unfortunately) # to pass them the whole Order this time
# Like for line items, most of the modifiers will simply add a field # to extra_price_fields, let's update the total with them
""" Remove all cart items """
def total_quantity(self): """ Returns the total quantity of all items in the cart """
""" This is a holder for the quantity of items in the cart and, obviously, a pointer to the actual Product being purchased :) """
# That will hold extra fields to display to the user # (ex. taxes, discount) # These must not be stored, since their components can be changed between # sessions / logins etc...
# We now loop over every registered price modifier, # most of them will simply add a field to extra_payment_fields
#=============================================================================== # Extensibility #=============================================================================== """ This overrides the various models with classes loaded from the corresponding setting if it exists. """ # Cart model Cart = load_class(CART_MODEL, 'SHOP_CART_MODEL') # Cart item model CartItem = load_class(CART_MODEL, 'SHOP_CARTITEM_MODEL') |