Skip to content
This repository
  • 4 commits
  • 4 files changed
  • 0 comments
  • 1 contributor
2  README.rst
Source Rendered
@@ -66,7 +66,7 @@ The following extensions are stable and ready for use:
66 66
 * django-oscar-jirafe_ - Integration with the Jirafe_ analytics package
67 67
 * django-oscar-paymentexpress_ - Integration with the `Payment Express`_ payment
68 68
   gateway
69  
-* django-oscar-accounts - Managed accounts (can be used for giftcard
  69
+* django-oscar-accounts_ - Managed accounts (can be used for giftcard
70 70
   functionality and loyalty schemes)
71 71
 
72 72
 .. _django-oscar-datacash: https://github.com/tangentlabs/django-oscar-datacash
2  oscar/apps/offer/models.py
@@ -681,7 +681,7 @@ def apply(self, basket, condition):
681 681
                 break
682 682
             quantity_affected = min(line.quantity_without_discount,
683 683
                                     max_affected_items - affected_items)
684  
-            line_discount = self.round(self.value / D(100.0) * price
  684
+            line_discount = self.round(self.value / D('100.0') * price
685 685
                                         * int(quantity_affected))
686 686
             line.discount(line_discount, quantity_affected)
687 687
 
2  oscar/templates/oscar/dashboard/layout.html
@@ -83,6 +83,6 @@
83 83
     {{ block.super }}
84 84
     <script src="{{ STATIC_URL }}oscar/js/oscar/ui.js" type="text/javascript" charset="utf-8"></script>
85 85
     <script src="{{ STATIC_URL }}oscar/js/oscar/dashboard.js" type="text/javascript" charset="utf-8"></script>
86  
-    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
  86
+    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
87 87
 	<script type="text/javascript">$(oscar.dashboard.init);</script>
88 88
 {% endblock %}
431  tests/unit/offer/benefit_tests.py
... ...
@@ -1,431 +0,0 @@
1  
-from decimal import Decimal as D
2  
-
3  
-from django.conf import settings
4  
-
5  
-from oscar.apps.basket.models import Basket
6  
-from oscar.apps.offer import models
7  
-from oscar.test.helpers import create_product
8  
-from tests.unit.offer import OfferTest
9  
-
10  
-
11  
-class PercentageDiscountBenefitTest(OfferTest):
12  
-
13  
-    def setUp(self):
14  
-        super(PercentageDiscountBenefitTest, self).setUp()
15  
-        self.benefit = models.PercentageDiscountBenefit(range=self.range, type="Percentage", value=D('15.00'))
16  
-        self.item = create_product(price=D('5.00'))
17  
-        self.original_offer_rounding_function = getattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION', None)
18  
-        if self.original_offer_rounding_function is not None:
19  
-            delattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION')
20  
-
21  
-    def tearDown(self):
22  
-        super(PercentageDiscountBenefitTest, self).tearDown()
23  
-        if self.original_offer_rounding_function is not None:
24  
-            settings.OSCAR_OFFER_ROUNDING_FUNCTION = self.original_offer_rounding_function
25  
-
26  
-    def test_no_discount_for_empty_basket(self):
27  
-        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
28  
-
29  
-    def test_no_discount_for_not_discountable_product(self):
30  
-        self.item.is_discountable = False
31  
-        self.item.save()
32  
-        self.basket.add_product(self.item, 1)
33  
-        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
34  
-
35  
-    def test_discount_for_single_item_basket(self):
36  
-        self.basket.add_product(self.item, 1)
37  
-        self.assertEquals(D('0.15') * D('5.00'), self.benefit.apply(self.basket))
38  
-
39  
-    def test_discount_for_multi_item_basket(self):
40  
-        self.basket.add_product(self.item, 3)
41  
-        self.assertEquals(D('3') * D('0.15') * D('5.00'), self.benefit.apply(self.basket))
42  
-
43  
-    def test_discount_for_multi_item_basket_with_max_affected_items_set(self):
44  
-        self.basket.add_product(self.item, 3)
45  
-        self.benefit.max_affected_items = 1
46  
-        self.assertEquals(D('0.15') * D('5.00'), self.benefit.apply(self.basket))
47  
-
48  
-    def test_discount_can_only_be_applied_once(self):
49  
-        self.basket.add_product(self.item, 3)
50  
-        self.benefit.apply(self.basket)
51  
-        second_discount = self.benefit.apply(self.basket)
52  
-        self.assertEquals(D('0.00'), second_discount)
53  
-
54  
-    def test_discount_can_be_applied_several_times_when_max_is_set(self):
55  
-        self.basket.add_product(self.item, 3)
56  
-        self.benefit.max_affected_items = 1
57  
-        for i in range(1, 4):
58  
-            self.assertTrue(self.benefit.apply(self.basket) > 0)
59  
-
60  
-
61  
-class TestAbsoluteDiscount(OfferTest):
62  
-
63  
-    def setUp(self):
64  
-        super(TestAbsoluteDiscount, self).setUp()
65  
-
66  
-        self.benefit = models.AbsoluteDiscountBenefit(
67  
-            range=self.range, type="Absolute", value=D('10.00'))
68  
-        self.item = create_product(price=D('5.00'))
69  
-
70  
-        self.original_offer_rounding_function = getattr(
71  
-            settings, 'OSCAR_OFFER_ROUNDING_FUNCTION', None)
72  
-        if self.original_offer_rounding_function is not None:
73  
-            delattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION')
74  
-
75  
-    def tearDown(self):
76  
-        if self.original_offer_rounding_function is not None:
77  
-            settings.OSCAR_OFFER_ROUNDING_FUNCTION = self.original_offer_rounding_function
78  
-
79  
-    def test_gives_no_discount_for_an_empty_basket(self):
80  
-        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
81  
-
82  
-    def test_gives_no_discount_for_a_non_discountable_product(self):
83  
-        product = create_product(price=D('5.00'), is_discountable=False)
84  
-        self.basket.add_product(product)
85  
-        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
86  
-
87  
-    def test_gives_correct_discount_for_single_item_basket_cheaper_than_threshold(self):
88  
-        product = create_product(price=D('5.00'))
89  
-        self.basket.add_product(product)
90  
-        self.assertEquals(D('5.00'), self.benefit.apply(self.basket))
91  
-
92  
-    def test_gives_correct_discount_for_single_item_basket_equal_to_threshold(self):
93  
-        product = create_product(price=D('10.00'))
94  
-        self.basket.add_product(product)
95  
-        self.assertEquals(D('10.00'), self.benefit.apply(self.basket))
96  
-
97  
-    def test_gives_correct_discount_for_single_item_basket_more_expensive_than_threshold(self):
98  
-        product = create_product(price=D('16.00'))
99  
-        self.basket.add_product(product)
100  
-        self.assertEquals(D('10.00'), self.benefit.apply(self.basket))
101  
-
102  
-    def test_gives_correct_discount_for_multi_item_basket_cheaper_than_threshold(self):
103  
-        product = create_product(price=D('2.00'))
104  
-        self.basket.add_product(product, 3)
105  
-        self.assertEquals(D('6.00'), self.benefit.apply(self.basket))
106  
-
107  
-    def test_gives_correct_discount_for_multi_item_basket_more_expensive_than_threshold(self):
108  
-        product = create_product(price=D('5.00'))
109  
-        self.basket.add_product(product, 3)
110  
-        self.assertEquals(D('10.00'), self.benefit.apply(self.basket))
111  
-
112  
-    def test_consumes_all_lines_for_multi_item_basket_cheaper_than_threshold(self):
113  
-        product = create_product(price=D('2.00'))
114  
-        self.basket.add_product(product, 3)
115  
-        self.benefit.apply(self.basket)
116  
-        for line in self.basket.all_lines():
117  
-            self.assertTrue(line.has_discount)
118  
-            self.assertEqual(0, line.quantity_without_discount)
119  
-
120  
-    def test_consumes_correct_quantity_for_multi_item_basket_more_expensive_than_threshold(self):
121  
-        product = create_product(price=D('6.00'))
122  
-        self.basket.add_product(product, 3)
123  
-        self.benefit.apply(self.basket)
124  
-        line = self.basket.all_lines()[0]
125  
-        self.assertTrue(line.has_discount)
126  
-        self.assertEqual(1, line.quantity_without_discount)
127  
-
128  
-    def test_gives_correct_discount_for_multi_item_basket_with_max_affected_items_set(self):
129  
-        product = create_product(price=D('5.00'))
130  
-        self.basket.add_product(product, 3)
131  
-        self.benefit.max_affected_items = 1
132  
-        self.assertEquals(D('5.00'), self.benefit.apply(self.basket))
133  
-
134  
-    def test_gives_correct_discounts_when_applied_multiple_times(self):
135  
-        product = create_product(price=D('5.00'))
136  
-        self.basket.add_product(product, 3)
137  
-
138  
-        self.assertEquals(D('10.00'), self.benefit.apply(self.basket))
139  
-        self.assertEquals(D('5.00'), self.benefit.apply(self.basket))
140  
-        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
141  
-
142  
-    def test_gives_correct_discounts_when_applied_multiple_times_with_condition(self):
143  
-        product = create_product(D('25000'))
144  
-        rng = models.Range.objects.create(name='Dummy')
145  
-        rng.included_products.add(product)
146  
-
147  
-        condition = models.ValueCondition(range=rng, type='Value', value=D('5000'))
148  
-
149  
-        self.basket.add_product(product, 5)
150  
-        benefit = models.AbsoluteDiscountBenefit(range=rng, type='Absolute', value=D('100'))
151  
-
152  
-        for _ in range(5):
153  
-            self.assertTrue(condition.is_satisfied(self.basket))
154  
-            self.assertEquals(D('100'), benefit.apply(self.basket, condition))
155  
-
156  
-        self.assertFalse(condition.is_satisfied(self.basket))
157  
-        self.assertEquals(D('0'), benefit.apply(self.basket, condition))
158  
-
159  
-    def test_consumes_all_products_for_heterogeneous_basket(self):
160  
-        rng = models.Range.objects.create(name='Dummy')
161  
-        products = [create_product(D('150')),
162  
-                    create_product(D('300')),
163  
-                    create_product(D('300'))]
164  
-        for product in products:
165  
-            rng.included_products.add(product)
166  
-
167  
-        condition = models.ValueCondition(range=rng, type='Value', value=D('500'))
168  
-
169  
-        basket = Basket.objects.create()
170  
-        for product in products:
171  
-            basket.add_product(product)
172  
-
173  
-        benefit = models.AbsoluteDiscountBenefit(range=rng, type='Absolute', value=D('100'))
174  
-
175  
-        self.assertTrue(condition.is_satisfied(basket))
176  
-        self.assertEquals(D('100'), benefit.apply(basket, condition))
177  
-        self.assertEquals(D('0'), benefit.apply(basket, condition))
178  
-
179  
-    def test_correctly_discounts_line(self):
180  
-        product = create_product(D('500'))
181  
-        rng = models.Range.objects.create(name='Dummy')
182  
-        rng.included_products.add(product)
183  
-
184  
-        condition = models.ValueCondition(range=rng, type='Value', value=D('500'))
185  
-        basket = Basket.objects.create()
186  
-        basket.add_product(product, 1)
187  
-
188  
-        benefit = models.AbsoluteDiscountBenefit(range=rng, type='Absolute', value=D('100'))
189  
-
190  
-        self.assertTrue(condition.is_satisfied(basket))
191  
-        self.assertEquals(D('100'), benefit.apply(basket, condition))
192  
-        self.assertEquals(D('100'), basket.all_lines()[0]._discount)
193  
-
194  
-    def test_discount_is_applied_to_lines(self):
195  
-        condition = models.CountCondition.objects.create(
196  
-            range=self.range, type="Count", value=1)
197  
-        self.basket.add_product(self.item, 1)
198  
-        self.benefit.apply(self.basket, condition)
199  
-        self.assertTrue(self.basket.all_lines()[0].has_discount)
200  
-
201  
-
202  
-class MultibuyDiscountBenefitTest(OfferTest):
203  
-
204  
-    def setUp(self):
205  
-        super(MultibuyDiscountBenefitTest, self).setUp()
206  
-        self.benefit = models.MultibuyDiscountBenefit(range=self.range, type="Multibuy", value=1)
207  
-        self.item = create_product(price=D('5.00'))
208  
-
209  
-    def test_no_discount_for_empty_basket(self):
210  
-        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
211  
-
212  
-    def test_discount_for_single_item_basket(self):
213  
-        self.basket.add_product(self.item, 1)
214  
-        self.assertEquals(D('5.00'), self.benefit.apply(self.basket))
215  
-
216  
-    def test_discount_for_multi_item_basket(self):
217  
-        self.basket.add_product(self.item, 3)
218  
-        self.assertEquals(D('5.00'), self.benefit.apply(self.basket))
219  
-
220  
-    def test_no_discount_for_not_discountable_product(self):
221  
-        self.item.is_discountable = False
222  
-        self.item.save()
223  
-        self.basket.add_product(self.item, 1)
224  
-        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
225  
-
226  
-    def test_discount_does_not_consume_item_if_in_condition_range(self):
227  
-        self.basket.add_product(self.item, 1)
228  
-        first_discount = self.benefit.apply(self.basket)
229  
-        self.assertEquals(D('5.00'), first_discount)
230  
-        second_discount = self.benefit.apply(self.basket)
231  
-        self.assertEquals(D('5.00'), second_discount)
232  
-
233  
-    def test_product_does_consume_item_if_not_in_condition_range(self):
234  
-        # Set up condition using a different range from benefit
235  
-        range = models.Range.objects.create(name="Small range")
236  
-        other_product = create_product(price=D('15.00'))
237  
-        range.included_products.add(other_product)
238  
-        cond = models.ValueCondition(range=range, type="Value", value=D('10.00'))
239  
-
240  
-        self.basket.add_product(self.item, 1)
241  
-        self.benefit.apply(self.basket, cond)
242  
-        line = self.basket.all_lines()[0]
243  
-        self.assertEqual(line.quantity_without_discount, 0)
244  
-
245  
-    def test_condition_consumes_most_expensive_lines_first(self):
246  
-        for i in range(10, 0, -1):
247  
-            product = create_product(price=D(i), title='%i'%i, upc='upc_%i' % i)
248  
-            self.basket.add_product(product, 1)
249  
-
250  
-        condition = models.CountCondition(range=self.range, type="Count", value=2)
251  
-
252  
-        self.assertTrue(condition.is_satisfied(self.basket))
253  
-        # consume 1 and 10
254  
-        first_discount = self.benefit.apply(self.basket, condition=condition)
255  
-        self.assertEquals(D('1.00'), first_discount)
256  
-
257  
-        self.assertTrue(condition.is_satisfied(self.basket))
258  
-        # consume 2 and 9
259  
-        second_discount = self.benefit.apply(self.basket, condition=condition)
260  
-        self.assertEquals(D('2.00'), second_discount)
261  
-
262  
-        self.assertTrue(condition.is_satisfied(self.basket))
263  
-        # consume 3 and 8
264  
-        third_discount = self.benefit.apply(self.basket, condition=condition)
265  
-        self.assertEquals(D('3.00'), third_discount)
266  
-
267  
-        self.assertTrue(condition.is_satisfied(self.basket))
268  
-        # consume 4 and 7
269  
-        fourth_discount = self.benefit.apply(self.basket, condition=condition)
270  
-        self.assertEquals(D('4.00'), fourth_discount)
271  
-
272  
-        self.assertTrue(condition.is_satisfied(self.basket))
273  
-        # consume 5 and 6
274  
-        fifth_discount = self.benefit.apply(self.basket, condition=condition)
275  
-        self.assertEquals(D('5.00'), fifth_discount)
276  
-
277  
-        # end of items (one not discounted item in basket)
278  
-        self.assertFalse(condition.is_satisfied(self.basket))
279  
-
280  
-    def test_condition_consumes_most_expensive_lines_first_when_products_are_repeated(self):
281  
-        for i in range(5, 0, -1):
282  
-            product = create_product(price=D(i), title='%i'%i, upc='upc_%i' % i)
283  
-            self.basket.add_product(product, 2)
284  
-
285  
-        condition = models.CountCondition(range=self.range, type="Count", value=2)
286  
-
287  
-        # initial basket: [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
288  
-        self.assertTrue(condition.is_satisfied(self.basket))
289  
-        # consume 1 and 5
290  
-        first_discount = self.benefit.apply(self.basket, condition=condition)
291  
-        self.assertEquals(D('1.00'), first_discount)
292  
-
293  
-        self.assertTrue(condition.is_satisfied(self.basket))
294  
-        # consume 1 and 5
295  
-        second_discount = self.benefit.apply(self.basket, condition=condition)
296  
-        self.assertEquals(D('1.00'), second_discount)
297  
-
298  
-        self.assertTrue(condition.is_satisfied(self.basket))
299  
-        # consume 2 and 4
300  
-        third_discount = self.benefit.apply(self.basket, condition=condition)
301  
-        self.assertEquals(D('2.00'), third_discount)
302  
-
303  
-        self.assertTrue(condition.is_satisfied(self.basket))
304  
-        # consume 2 and 4
305  
-        third_discount = self.benefit.apply(self.basket, condition=condition)
306  
-        self.assertEquals(D('2.00'), third_discount)
307  
-
308  
-        self.assertTrue(condition.is_satisfied(self.basket))
309  
-        # consume 3 and 3
310  
-        third_discount = self.benefit.apply(self.basket, condition=condition)
311  
-        self.assertEquals(D('3.00'), third_discount)
312  
-
313  
-        # end of items (one not discounted item in basket)
314  
-        self.assertFalse(condition.is_satisfied(self.basket))
315  
-
316  
-    def test_products_with_no_stockrecord_are_handled_ok(self):
317  
-        self.basket.add_product(self.item, 3)
318  
-        self.basket.add_product(create_product())
319  
-        condition = models.CountCondition(range=self.range, type="Count", value=3)
320  
-        self.benefit.apply(self.basket, condition)
321  
-
322  
-
323  
-class FixedPriceBenefitTest(OfferTest):
324  
-
325  
-    def setUp(self):
326  
-        super(FixedPriceBenefitTest, self).setUp()
327  
-        self.benefit = models.FixedPriceBenefit(range=self.range, type="FixedPrice", value=D('10.00'))
328  
-
329  
-    def test_correct_discount_for_count_condition(self):
330  
-        products = [create_product(D('7.00')),
331  
-                    create_product(D('8.00')),
332  
-                    create_product(D('12.00'))]
333  
-
334  
-        # Create range that includes the products
335  
-        range = models.Range.objects.create(name="Dummy range")
336  
-        for product in products:
337  
-            range.included_products.add(product)
338  
-        condition = models.CountCondition(range=range, type="Count", value=3)
339  
-
340  
-        # Create basket that satisfies condition but with one extra product
341  
-        basket = Basket.objects.create()
342  
-        [basket.add_product(p, 2) for p in products]
343  
-
344  
-        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=D('20.00'))
345  
-        self.assertEquals(D('2.00'), benefit.apply(basket, condition))
346  
-        self.assertEquals(D('12.00'), benefit.apply(basket, condition))
347  
-        self.assertEquals(D('0.00'), benefit.apply(basket, condition))
348  
-
349  
-    def test_correct_discount_is_returned(self):
350  
-        products = [create_product(D('8.00')), create_product(D('4.00'))]
351  
-        range = models.Range.objects.create(name="Dummy range")
352  
-        for product in products:
353  
-            range.included_products.add(product)
354  
-            range.included_products.add(product)
355  
-
356  
-        basket = Basket.objects.create()
357  
-        [basket.add_product(p) for p in products]
358  
-
359  
-        condition = models.CoverageCondition(range=range, type="Coverage", value=2)
360  
-        discount = self.benefit.apply(basket, condition)
361  
-        self.assertEquals(D('2.00'), discount)
362  
-
363  
-    def test_no_discount_when_product_not_discountable(self):
364  
-        product = create_product(D('18.00'))
365  
-        product.is_discountable = False
366  
-        product.save()
367  
-
368  
-        product_range = models.Range.objects.create(name="Dummy range")
369  
-        product_range.included_products.add(product)
370  
-
371  
-        basket = Basket.objects.create()
372  
-        basket.add_product(product)
373  
-
374  
-        condition = models.CoverageCondition(range=product_range, type="Coverage", value=1)
375  
-        discount = self.benefit.apply(basket, condition)
376  
-        self.assertEquals(D('0.00'), discount)
377  
-
378  
-    def test_no_discount_is_returned_when_value_is_greater_than_product_total(self):
379  
-        products = [create_product(D('4.00')), create_product(D('4.00'))]
380  
-        range = models.Range.objects.create(name="Dummy range")
381  
-        for product in products:
382  
-            range.included_products.add(product)
383  
-            range.included_products.add(product)
384  
-
385  
-        basket = Basket.objects.create()
386  
-        [basket.add_product(p) for p in products]
387  
-
388  
-        condition = models.CoverageCondition(range=range, type="Coverage", value=2)
389  
-        discount = self.benefit.apply(basket, condition)
390  
-        self.assertEquals(D('0.00'), discount)
391  
-
392  
-    def test_discount_when_more_products_than_required(self):
393  
-        products = [create_product(D('4.00')),
394  
-                    create_product(D('8.00')),
395  
-                    create_product(D('12.00'))]
396  
-
397  
-        # Create range that includes the products
398  
-        range = models.Range.objects.create(name="Dummy range")
399  
-        for product in products:
400  
-            range.included_products.add(product)
401  
-        condition = models.CoverageCondition(range=range, type="Coverage", value=3)
402  
-
403  
-        # Create basket that satisfies condition but with one extra product
404  
-        basket = Basket.objects.create()
405  
-        [basket.add_product(p) for p in products]
406  
-        basket.add_product(products[0])
407  
-
408  
-        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=D('20.00'))
409  
-        discount = benefit.apply(basket, condition)
410  
-        self.assertEquals(D('4.00'), discount)
411  
-
412  
-    def test_discount_when_applied_twice(self):
413  
-        products = [create_product(D('4.00')),
414  
-                    create_product(D('8.00')),
415  
-                    create_product(D('12.00'))]
416  
-
417  
-        # Create range that includes the products
418  
-        range = models.Range.objects.create(name="Dummy range")
419  
-        for product in products:
420  
-            range.included_products.add(product)
421  
-        condition = models.CoverageCondition(range=range, type="Coverage", value=3)
422  
-
423  
-        # Create basket that satisfies condition but with one extra product
424  
-        basket = Basket.objects.create()
425  
-        [basket.add_product(p, 2) for p in products]
426  
-
427  
-        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=D('20.00'))
428  
-        first_discount = benefit.apply(basket, condition)
429  
-        self.assertEquals(D('4.00'), first_discount)
430  
-        second_discount = benefit.apply(basket, condition)
431  
-        self.assertEquals(D('4.00'), second_discount)

No commit comments for this range

Something went wrong with that request. Please try again.