Browse Source

Excise partner wrapper functionality

master
David Winterbottom 11 years ago
parent
commit
bb7050a5a9

+ 4
- 0
docs/source/releases/v0.8.rst View File

@@ -17,6 +17,10 @@ Overview
17 17
 
18 18
 Oscar now has a demo site customised for the US!
19 19
 
20
+Lots of methods deprecated in the 0.6 release have now been removed.
21
+Specifically, the partner "wrapper" functionality is now gone. All price and
22
+availability logic now needs to be handled with strategies.
23
+
20 24
 .. _compatibility_of_0.8:
21 25
 
22 26
 Compatibility

+ 0
- 35
oscar/apps/partner/abstract_models.py View File

@@ -1,46 +1,11 @@
1 1
 from django.db import models
2 2
 from django.conf import settings
3 3
 from django.utils.translation import ugettext_lazy as _
4
-from django.utils.importlib import import_module as django_import_module
5 4
 
6
-from oscar.core.loading import get_model, get_class
7 5
 from oscar.core.compat import AUTH_USER_MODEL
8 6
 from oscar.models.fields import AutoSlugField
9 7
 from oscar.apps.partner.exceptions import InvalidStockAdjustment
10 8
 
11
-DefaultWrapper = get_class('partner.wrappers', 'DefaultWrapper')
12
-
13
-
14
-# Cache dict of partner_id => availability wrapper instance
15
-partner_wrappers = None
16
-
17
-default_wrapper = DefaultWrapper()
18
-
19
-
20
-def get_partner_wrapper(partner_id):
21
-    """
22
-    Returns the appropriate partner wrapper given the partner's PK
23
-    """
24
-    if partner_wrappers is None:
25
-        _load_partner_wrappers()
26
-    return partner_wrappers.get(partner_id, default_wrapper)
27
-
28
-
29
-def _load_partner_wrappers():
30
-    # Prime cache of partner wrapper dict
31
-    global partner_wrappers
32
-    partner_wrappers = {}
33
-    Partner = get_model('partner', 'Partner')
34
-    for code, class_str in settings.OSCAR_PARTNER_WRAPPERS.items():
35
-        try:
36
-            partner = Partner.objects.get(code=code)
37
-        except Partner.DoesNotExist:
38
-            continue
39
-        else:
40
-            module_path, klass = class_str.rsplit('.', 1)
41
-            module = django_import_module(module_path)
42
-            partner_wrappers[partner.id] = getattr(module, klass)()
43
-
44 9
 
45 10
 class AbstractPartner(models.Model):
46 11
     """

+ 0
- 97
oscar/apps/partner/wrappers.py View File

@@ -1,97 +0,0 @@
1
-from decimal import Decimal as D
2
-
3
-from django.utils.translation import ugettext_lazy as _
4
-
5
-
6
-class DefaultWrapper(object):
7
-    """
8
-    Default stockrecord wrapper
9
-    """
10
-    CODE_IN_STOCK = 'instock'
11
-    CODE_AVAILABLE = 'available'
12
-    CODE_UNAVAILABLE = 'outofstock'
13
-
14
-    def is_available_to_buy(self, stockrecord):
15
-        """
16
-        Test whether a product is available to buy.
17
-
18
-        This is used to determine whether to show the add-to-basket button.
19
-        """
20
-        if stockrecord.num_in_stock is None:
21
-            return True
22
-        return stockrecord.net_stock_level > 0
23
-
24
-    def is_purchase_permitted(self, stockrecord, user=None, quantity=1,
25
-                              product=None):
26
-        """
27
-        Test whether a particular purchase is possible (is a user buying a
28
-        given quantity of the product)
29
-        """
30
-        # check, if fetched product is provided, to avoid db call
31
-        product = product or stockrecord.product
32
-        if not self.is_available_to_buy(stockrecord):
33
-            return False, _("'%s' is unavailable to purchase") % product.title
34
-        max_qty = self.max_purchase_quantity(stockrecord, user, product)
35
-        if max_qty is None:
36
-            return True, None
37
-        if max_qty < quantity:
38
-            return False, _("A maximum of %(max)d can be bought" %
39
-                            {'max': max_qty})
40
-        return True, None
41
-
42
-    def max_purchase_quantity(self, stockrecord, user=None, product=None):
43
-        """
44
-        Return the maximum available purchase quantity for a given user
45
-        """
46
-        product = product or stockrecord.product
47
-
48
-        if not product.get_product_class().track_stock:
49
-            return None
50
-        if stockrecord.num_in_stock is None:
51
-            return None
52
-        return stockrecord.net_stock_level
53
-
54
-    def availability_code(self, stockrecord):
55
-        """
56
-        Return a code for the availability of this product.
57
-
58
-        This is normally used within CSS to add icons to stock messages
59
-
60
-        :param oscar.apps.partner.models.StockRecord stockrecord: stockrecord
61
-        instance
62
-        """
63
-        if stockrecord.net_stock_level > 0:
64
-            return self.CODE_IN_STOCK
65
-        if self.is_available_to_buy(stockrecord):
66
-            return self.CODE_AVAILABLE
67
-        return self.CODE_UNAVAILABLE
68
-
69
-    def availability(self, stockrecord):
70
-        """
71
-        Return an availability message for the passed stockrecord.
72
-
73
-        :param oscar.apps.partner.models.StockRecord stockrecord: stockrecord
74
-        instance
75
-        """
76
-        if stockrecord.net_stock_level > 0:
77
-            return _("In stock (%d available)") % stockrecord.net_stock_level
78
-        if self.is_available_to_buy(stockrecord):
79
-            return _('Available')
80
-        return _("Not available")
81
-
82
-    def dispatch_date(self, stockrecord):
83
-        """
84
-        We don't provide a default value as it could be confusing.  Subclass
85
-        and override this method to provide estimated dispatch dates
86
-        """
87
-        return None
88
-
89
-    def lead_time(self, stockrecord):
90
-        """
91
-        We don't provide a default value as it could be confusing.  Subclass
92
-        and override this method to provide estimated dispatch dates
93
-        """
94
-        return None
95
-
96
-    def calculate_tax(self, stockrecord):
97
-        return D('0.00')

+ 0
- 3
oscar/defaults.py View File

@@ -38,9 +38,6 @@ OSCAR_PRODUCTS_PER_PAGE = 20
38 38
 # Checkout
39 39
 OSCAR_ALLOW_ANON_CHECKOUT = False
40 40
 
41
-# Partners
42
-OSCAR_PARTNER_WRAPPERS = {}
43
-
44 41
 # Promotions
45 42
 COUNTDOWN, LIST, SINGLE_PRODUCT, TABBED_BLOCK = (
46 43
     'Countdown', 'List', 'SingleProduct', 'TabbedBlock')

+ 1
- 12
tests/unit/partner/model_tests.py View File

@@ -1,26 +1,15 @@
1
-import six
2 1
 from decimal import Decimal as D
3 2
 from oscar.core.loading import get_model
4 3
 
5 4
 from django.test import TestCase
6 5
 
7
-from oscar.test import factories, decorators
8
-from oscar.apps.partner import abstract_models
6
+from oscar.test import factories
9 7
 
10 8
 Partner = get_model('partner', 'Partner')
11 9
 PartnerAddress = get_model('partner', 'PartnerAddress')
12 10
 Country = get_model('address', 'Country')
13 11
 
14 12
 
15
-class DummyWrapper(object):
16
-
17
-    def availability(self, stockrecord):
18
-        return 'Dummy response'
19
-
20
-    def dispatch_date(self, stockrecord):
21
-        return "Another dummy response"
22
-
23
-
24 13
 class TestStockRecord(TestCase):
25 14
 
26 15
     def setUp(self):

+ 0
- 165
tests/unit/partner/wrapper_tests.py View File

@@ -1,165 +0,0 @@
1
-from decimal import Decimal as D
2
-
3
-from django.test import TestCase
4
-
5
-from oscar.apps.partner.wrappers import DefaultWrapper
6
-from oscar.apps.catalogue.models import Product, ProductClass
7
-from oscar.apps.partner.models import StockRecord
8
-
9
-
10
-class TestStockRecordWithNullStockLevel(TestCase):
11
-    """
12
-    Stock record with num_in_stock=None
13
-    """
14
-
15
-    def setUp(self):
16
-        self.wrapper = DefaultWrapper()
17
-        self.product = Product()
18
-        self.product.product_class = ProductClass()
19
-        self.record = StockRecord(num_in_stock=None, product=self.product)
20
-
21
-    def test_is_available_to_buy(self):
22
-        self.assertTrue(self.wrapper.is_available_to_buy(self.record))
23
-
24
-    def test_permits_purchase(self):
25
-        is_permitted, reason = self.wrapper.is_purchase_permitted(
26
-            self.record)
27
-        self.assertTrue(is_permitted)
28
-
29
-    def test_has_no_max_purchase_quantity(self):
30
-        self.assertIsNone(self.wrapper.max_purchase_quantity(self.record))
31
-
32
-    def test_returns_available_code(self):
33
-        self.assertEqual(DefaultWrapper.CODE_AVAILABLE,
34
-                         self.wrapper.availability_code(self.record))
35
-
36
-    def test_returns_correct_availability_message(self):
37
-        self.assertEqual("Available",
38
-                         self.wrapper.availability(self.record))
39
-
40
-    def test_returns_no_estimated_dispatch_date(self):
41
-        self.assertIsNone(self.wrapper.dispatch_date(self.record))
42
-
43
-    def test_returns_no_estimated_lead_time(self):
44
-        self.assertIsNone(self.wrapper.lead_time(self.record))
45
-
46
-    def test_returns_zero_tax(self):
47
-        self.assertEqual(D('0.00'), self.wrapper.calculate_tax(self.record))
48
-
49
-
50
-class TestStockRecordOfDigitalProduct(TestCase):
51
-
52
-    def setUp(self):
53
-        self.wrapper = DefaultWrapper()
54
-        self.product = Product()
55
-        self.product.product_class = ProductClass(track_stock=False)
56
-        self.record = StockRecord(num_in_stock=None, product=self.product)
57
-
58
-    def test_is_available_to_buy(self):
59
-        self.assertTrue(self.wrapper.is_available_to_buy(self.record))
60
-
61
-    def test_permits_purchase(self):
62
-        is_permitted, reason = self.wrapper.is_purchase_permitted(
63
-            self.record)
64
-        self.assertTrue(is_permitted)
65
-
66
-    def test_has_no_max_purchase_quantity(self):
67
-        self.assertIsNone(self.wrapper.max_purchase_quantity(self.record))
68
-
69
-    def test_returns_available_code(self):
70
-        self.assertEqual(DefaultWrapper.CODE_AVAILABLE,
71
-                         self.wrapper.availability_code(self.record))
72
-
73
-    def test_returns_correct_availability_message(self):
74
-        self.assertEqual("Available",
75
-                         self.wrapper.availability(self.record))
76
-
77
-    def test_returns_no_estimated_dispatch_date(self):
78
-        self.assertIsNone(self.wrapper.dispatch_date(self.record))
79
-
80
-    def test_returns_no_estimated_lead_time(self):
81
-        self.assertIsNone(self.wrapper.lead_time(self.record))
82
-
83
-    def test_returns_zero_tax(self):
84
-        self.assertEqual(D('0.00'), self.wrapper.calculate_tax(self.record))
85
-
86
-
87
-class TestStockRecordOfZeroStockProduct(TestCase):
88
-
89
-    def setUp(self):
90
-        self.wrapper = DefaultWrapper()
91
-        self.product = Product()
92
-        self.product.product_class = ProductClass()
93
-        self.record = StockRecord(num_in_stock=0, product=self.product)
94
-
95
-    def test_is_not_available_to_buy(self):
96
-        self.assertFalse(self.wrapper.is_available_to_buy(self.record))
97
-
98
-    def test_does_not_permit_purchase(self):
99
-        is_permitted, reason = self.wrapper.is_purchase_permitted(
100
-            self.record)
101
-        self.assertFalse(is_permitted)
102
-
103
-    def test_has_zero_max_purchase_quantity(self):
104
-        self.assertEqual(0, self.wrapper.max_purchase_quantity(self.record))
105
-
106
-    def test_returns_unavailable_code(self):
107
-        self.assertEqual(DefaultWrapper.CODE_UNAVAILABLE,
108
-                         self.wrapper.availability_code(self.record))
109
-
110
-    def test_returns_correct_availability_message(self):
111
-        self.assertEqual("Not available",
112
-                         self.wrapper.availability(self.record))
113
-
114
-    def test_returns_no_estimated_dispatch_date(self):
115
-        self.assertIsNone(self.wrapper.dispatch_date(self.record))
116
-
117
-    def test_returns_no_estimated_lead_time(self):
118
-        self.assertIsNone(self.wrapper.lead_time(self.record))
119
-
120
-    def test_returns_zero_tax(self):
121
-        self.assertEqual(D('0.00'), self.wrapper.calculate_tax(self.record))
122
-
123
-
124
-class TestStockRecordWithPositiveStock(TestCase):
125
-
126
-    def setUp(self):
127
-        self.wrapper = DefaultWrapper()
128
-        self.product = Product()
129
-        self.product.product_class = ProductClass()
130
-        self.record = StockRecord(num_in_stock=5, product=self.product)
131
-
132
-    def test_is_available_to_buy(self):
133
-        self.assertTrue(self.wrapper.is_available_to_buy(self.record))
134
-
135
-    def test_does_permit_purchase_for_smaller_quantities(self):
136
-        for x in range(1, 6):
137
-            is_permitted, reason = self.wrapper.is_purchase_permitted(
138
-                self.record, quantity=x)
139
-            self.assertTrue(is_permitted)
140
-
141
-    def test_does_not_permit_purchase_for_larger_quantities(self):
142
-        for x in range(6, 10):
143
-            is_permitted, reason = self.wrapper.is_purchase_permitted(
144
-                self.record, quantity=x)
145
-            self.assertFalse(is_permitted)
146
-
147
-    def test_has_correct_max_purchase_quantity(self):
148
-        self.assertEqual(5, self.wrapper.max_purchase_quantity(self.record))
149
-
150
-    def test_returns_available_code(self):
151
-        self.assertEqual(DefaultWrapper.CODE_IN_STOCK,
152
-                         self.wrapper.availability_code(self.record))
153
-
154
-    def test_returns_correct_availability_message(self):
155
-        self.assertEqual("In stock (5 available)",
156
-                         self.wrapper.availability(self.record))
157
-
158
-    def test_returns_no_estimated_dispatch_date(self):
159
-        self.assertIsNone(self.wrapper.dispatch_date(self.record))
160
-
161
-    def test_returns_no_estimated_lead_time(self):
162
-        self.assertIsNone(self.wrapper.lead_time(self.record))
163
-
164
-    def test_returns_zero_tax(self):
165
-        self.assertEqual(D('0.00'), self.wrapper.calculate_tax(self.record))

Loading…
Cancel
Save