mirumee / satchless
1 6
from ..item import ItemSet, ItemLine
2

3

4 6
class CartLine(ItemLine):
5
    """
6
    Represents a cart line, ie. an ItemLine suitable for Cart use
7
    """
8 6
    def __init__(self, product, quantity, data=None):
9 6
        self.product = product
10 6
        self.quantity = quantity
11 6
        self.data = data
12

13 6
    def __eq__(self, other):
14 6
        if not isinstance(other, CartLine):
15 6
            return NotImplemented
16

17 6
        return (self.product == other.product and
18
                self.quantity == other.quantity and
19
                self.data == other.data)
20

21 6
    def __ne__(self, other):
22
        return not self == other  # pragma: no cover
23

24 6
    def __repr__(self):
25 6
        return 'CartLine(product=%r, quantity=%r, data=%r)' % (
26
            self.product, self.quantity, self.data)
27

28 6
    def __getstate__(self):
29 6
        return (self.product, self.quantity, self.data)
30

31 6
    def __setstate__(self, data):
32 6
        self.product, self.quantity, self.data = data
33

34 6
    def get_quantity(self):
35 6
        return self.quantity
36

37 6
    def get_price_per_item(self, **kwargs):
38 6
        return self.product.get_price(**kwargs)
39

40

41 6
class Cart(ItemSet):
42
    """
43
    Represents a Cart (Shopping Cart, Basket, etc.)
44

45
    Cart.modified:
46
        'Dirty' flag in case you need to sync the cart to a persistent storage
47
    """
48

49 6
    def __init__(self, items=None):
50 6
        self._state = []
51 6
        self.modified = False
52 6
        items = items or []
53 6
        for l in items:
54 6
            self.add(l.product, l.quantity, l.data, replace=True)
55

56 6
    def __repr__(self):
57 6
        return 'Cart(%r)' % (list(self),)
58

59 6
    def __iter__(self):
60 6
        return iter(self._state)
61

62 6
    def __getstate__(self):
63
        # return a tuple as __getstate__ *must* return a truthy value
64 6
        return (self._state,)
65

66 6
    def __setstate__(self, state):
67 6
        (self._state,) = state
68 6
        self.modified = False
69

70 6
    def __len__(self):
71 6
        return len(self._state)
72

73 6
    def __bool__(self):
74 6
        return bool(self._state)
75

76 6
    def __getitem__(self, key):
77 6
        return self._state[key]
78

79 6
    def count(self):
80 6
        return sum([item.get_quantity() for item in self._state])
81

82 6
    def check_quantity(self, product, quantity, data):
83 6
        if hasattr(product, 'check_quantity'):
84 6
            return product.check_quantity(quantity)
85

86 6
    def clear(self):
87 6
        self._state = []
88 6
        self.modified = True
89

90 6
    def create_line(self, product, quantity, data):
91 6
        return CartLine(product, quantity, data=data)
92

93 6
    def get_line(self, product, data=None):
94 6
        return next(
95
            (cart_line for cart_line in self._state
96
             if cart_line.product == product and cart_line.data == data),
97
            None)
98

99 6
    def _get_or_create_line(self, product, quantity, data):
100 6
        cart_line = self.get_line(product, data)
101 6
        if cart_line:
102 6
            return (False, cart_line)
103
        else:
104 6
            return (True, self.create_line(product, quantity, data))
105

106 6
    def add(self, product, quantity=1, data=None, replace=False,
107
            check_quantity=True):
108 6
        created, cart_line = self._get_or_create_line(product, 0, data)
109

110 6
        if replace:
111 6
            new_quantity = quantity
112
        else:
113 6
            new_quantity = cart_line.quantity + quantity
114

115 6
        if new_quantity < 0:
116 6
            raise ValueError('%r is not a valid quantity (results in %r)' % (
117
                quantity, new_quantity))
118

119 6
        if check_quantity:
120 6
            self.check_quantity(product, new_quantity, data)
121

122 6
        cart_line.quantity = new_quantity
123

124 6
        if not cart_line.quantity and not created:
125 6
            self._state.remove(cart_line)
126 6
            self.modified = True
127 6
        elif cart_line.quantity and created:
128 6
            self._state.append(cart_line)
129 6
            self.modified = True
130 6
        elif not created:
131 6
            self.modified = True

Read our documentation on viewing source code .

Loading