Quellcode durchsuchen

Merge branch 'releases/0.3'

Conflicts:
	oscar/__init__.py
master
David Winterbottom vor 13 Jahren
Ursprung
Commit
c234388496

+ 13
- 2
CHANGELOG.rst Datei anzeigen

2
 Changelog
2
 Changelog
3
 =========
3
 =========
4
 
4
 
5
-0.3 
6
----
5
+0.3.2
6
+-----
7
+
8
+* Bug fix for basket calculations
9
+* Bug fix for absolute discount benefit calculations
10
+
11
+0.3.1 - 2012-08-08
12
+------------------
13
+
14
+* Now including the translation files.
15
+
16
+0.3 - 2012-08-08
17
+----------------
7
 
18
 
8
 * i18n support added - Oscar now ships with .po files for seven languages.
19
 * i18n support added - Oscar now ships with .po files for seven languages.
9
   Translation files are welcome.
20
   Translation files are welcome.

+ 6
- 4
oscar/app.py Datei anzeigen

14
 
14
 
15
 class Shop(Application):
15
 class Shop(Application):
16
     name = None
16
     name = None
17
-    
17
+
18
     catalogue_app = catalogue_app
18
     catalogue_app = catalogue_app
19
     customer_app = customer_app
19
     customer_app = customer_app
20
     basket_app = basket_app
20
     basket_app = basket_app
23
     search_app = search_app
23
     search_app = search_app
24
     dashboard_app = dashboard_app
24
     dashboard_app = dashboard_app
25
     offer_app = offer_app
25
     offer_app = offer_app
26
-    
26
+
27
     def get_urls(self):
27
     def get_urls(self):
28
         urlpatterns = patterns('',
28
         urlpatterns = patterns('',
29
             (r'^products/', include(self.catalogue_app.urls)),
29
             (r'^products/', include(self.catalogue_app.urls)),
39
             # from working.
39
             # from working.
40
             url(r'^password-reset/$', auth_views.password_reset, name='password-reset'),
40
             url(r'^password-reset/$', auth_views.password_reset, name='password-reset'),
41
             url(r'^password-reset/done/$', auth_views.password_reset_done, name='password-reset-done'),
41
             url(r'^password-reset/done/$', auth_views.password_reset_done, name='password-reset-done'),
42
-            url(r'^password-reset/confirm/$', auth_views.password_reset_confirm, name='password-reset-confirm'),
42
+            url(r'^password-reset/confirm/(?P<uidb36>[0-9A-Za-z]{1,13})-(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
43
+                auth_views.password_reset_confirm, name='password-reset-confirm'),
43
             url(r'^password-reset/complete/$', auth_views.password_reset_complete, name='password-reset-complete'),
44
             url(r'^password-reset/complete/$', auth_views.password_reset_complete, name='password-reset-complete'),
44
 
45
 
45
             (r'', include(self.promotions_app.urls)),
46
             (r'', include(self.promotions_app.urls)),
46
         )
47
         )
47
         return urlpatterns
48
         return urlpatterns
48
-    
49
+
50
+
49
 # 'shop' kept for legacy projects - 'application' is a better name
51
 # 'shop' kept for legacy projects - 'application' is a better name
50
 shop = application = Shop()
52
 shop = application = Shop()

+ 1
- 1
oscar/apps/basket/views.py Datei anzeigen

24
     form_class = BasketLineForm
24
     form_class = BasketLineForm
25
     extra = 0
25
     extra = 0
26
     can_delete = True
26
     can_delete = True
27
-    template_name='basket/basket.html'
27
+    template_name = 'basket/basket.html'
28
 
28
 
29
     def get_queryset(self):
29
     def get_queryset(self):
30
         return self.request.basket.all_lines()
30
         return self.request.basket.all_lines()

+ 11
- 2
oscar/apps/offer/models.py Datei anzeigen

187
     description = __unicode__
187
     description = __unicode__
188
 
188
 
189
     def consume_items(self, basket, lines=None):
189
     def consume_items(self, basket, lines=None):
190
-        return ()
190
+        raise NotImplementedError("This method should never be called - "
191
+                                  "ensure you are using the correct proxy model")
191
 
192
 
192
     def is_satisfied(self, basket):
193
     def is_satisfied(self, basket):
193
         """
194
         """
421
         consumed_products = []
422
         consumed_products = []
422
         value = self.value if value is None else value
423
         value = self.value if value is None else value
423
         for line in lines:
424
         for line in lines:
425
+
424
             if self.can_apply_condition(line.product):
426
             if self.can_apply_condition(line.product):
425
                 quantity_to_consume = min(line.quantity_without_discount,
427
                 quantity_to_consume = min(line.quantity_without_discount,
426
                                           value - len(consumed_products))
428
                                           value - len(consumed_products))
649
 
651
 
650
                 # Update line with discounts
652
                 # Update line with discounts
651
                 line_discount = self.round(min(remaining_discount, quantity_affected * price))
653
                 line_discount = self.round(min(remaining_discount, quantity_affected * price))
652
-                line.discount(line_discount, quantity_affected)
654
+                if condition:
655
+                    # Pass zero as quantity to avoid double consumption
656
+                    line.discount(line_discount, 0)
657
+                else:
658
+                    line.discount(line_discount, quantity_affected)
653
 
659
 
654
                 # Update loop vars
660
                 # Update loop vars
655
                 affected_items += quantity_affected
661
                 affected_items += quantity_affected
656
                 remaining_discount -= line_discount
662
                 remaining_discount -= line_discount
657
                 discount += line_discount
663
                 discount += line_discount
658
 
664
 
665
+        if discount > 0 and condition:
666
+            condition.consume_items(basket)
667
+
659
         return discount
668
         return discount
660
 
669
 
661
 
670
 

+ 1
- 0
oscar/templates/oscar/customer/login_registration.html Datei anzeigen

24
             <h2>{% trans 'Log In' %}</h2>
24
             <h2>{% trans 'Log In' %}</h2>
25
             {% csrf_token %}
25
             {% csrf_token %}
26
             {% include "partials/form_fields.html" with form=login_form %}
26
             {% include "partials/form_fields.html" with form=login_form %}
27
+			<p><a href="{% url password-reset %}">{% trans "I've forgotten my password" %}</a></p>
27
             <button name="login_submit" type="submit" value="Log In" class="btn btn-large btn-primary">{% trans 'Log In' %}</button>
28
             <button name="login_submit" type="submit" value="Log In" class="btn btn-large btn-primary">{% trans 'Log In' %}</button>
28
         </form>
29
         </form>
29
     </div>
30
     </div>

+ 1
- 1
oscar/templates/oscar/dashboard/layout.html Datei anzeigen

8
 	<link rel="stylesheet" href="{{ STATIC_URL }}oscar/css/dashboard.css" />
8
 	<link rel="stylesheet" href="{{ STATIC_URL }}oscar/css/dashboard.css" />
9
 {% endblock %}
9
 {% endblock %}
10
 
10
 
11
-{% block extrahead %} {%endblock extrahead %}
11
+{% block extrahead %} {% endblock extrahead %}
12
 
12
 
13
 {% block title %}
13
 {% block title %}
14
 {% trans "Dashboard" %} | {{ block.super }}
14
 {% trans "Dashboard" %} | {{ block.super }}

+ 1
- 1
oscar/templates/oscar/layout.html Datei anzeigen

18
             {% include "partials/nav_primary.html" %}
18
             {% include "partials/nav_primary.html" %}
19
         {% endblock %}
19
         {% endblock %}
20
     </header>
20
     </header>
21
-    <div class="container-fluid page">
21
+	<div class="container-fluid page">
22
         {% block header %}{% endblock %}
22
         {% block header %}{% endblock %}
23
         <div class="page_inner">
23
         <div class="page_inner">
24
             {% block breadcrumbs %}{% endblock %}
24
             {% block breadcrumbs %}{% endblock %}

+ 11
- 1
oscar/templates/oscar/registration/password_reset_complete.html Datei anzeigen

3
 
3
 
4
 {% block title %}{% trans 'Password reset complete' %} | {{ block.super }}{% endblock %}
4
 {% block title %}{% trans 'Password reset complete' %} | {{ block.super }}{% endblock %}
5
 
5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Password reset complete' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6
 {% block content %}
16
 {% block content %}
7
 	<h1>{% trans 'Password reset complete' %}</h1>
17
 	<h1>{% trans 'Password reset complete' %}</h1>
8
 	<p>{% trans "Your password has been set.  You may go ahead and log in now." %}</p>
18
 	<p>{% trans "Your password has been set.  You may go ahead and log in now." %}</p>
9
-	<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
19
+	<p><a href="{{ login_url }}" class="btn btn-large btn-primary">{% trans 'Log in' %}</a></p>
10
 {% endblock %}
20
 {% endblock %}

+ 12
- 2
oscar/templates/oscar/registration/password_reset_confirm.html Datei anzeigen

3
 
3
 
4
 {% block title %}{% trans 'Password reset confirm' %} | {{ block.super }}{% endblock %}
4
 {% block title %}{% trans 'Password reset confirm' %} | {{ block.super }}{% endblock %}
5
 
5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Enter new password' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6
 {% block content %}
16
 {% block content %}
7
 
17
 
8
 {% if validlink %}
18
 {% if validlink %}
11
 
21
 
12
 <p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
22
 <p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
13
 
23
 
14
-<form action="" method="post">{% csrf_token %}
24
+<form id="password_reset_form" action="" method="post">{% csrf_token %}
15
 {{ form.new_password1.errors }}
25
 {{ form.new_password1.errors }}
16
 <p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
26
 <p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
17
 {{ form.new_password2.errors }}
27
 {{ form.new_password2.errors }}
18
 <p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
28
 <p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
19
-<p><input type="submit" value="{% trans 'Change my password' %}" /></p>
29
+<p><button class="btn btn-primary btn-large" type="submit">{% trans 'Change my password' %}</button></p>
20
 </form>
30
 </form>
21
 
31
 
22
 {% else %}
32
 {% else %}

+ 10
- 0
oscar/templates/oscar/registration/password_reset_done.html Datei anzeigen

3
 
3
 
4
 {% block title %}{% trans 'Password reset successful' %} | {{ block.super }}{% endblock %}
4
 {% block title %}{% trans 'Password reset successful' %} | {{ block.super }}{% endblock %}
5
 
5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Password reset sent' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6
 {% block content %}
16
 {% block content %}
7
 
17
 
8
     <h1>{% trans 'Password reset successful' %}</h1>
18
     <h1>{% trans 'Password reset successful' %}</h1>

+ 11
- 1
oscar/templates/oscar/registration/password_reset_form.html Datei anzeigen

3
 
3
 
4
 {% block title %}{% trans 'Password reset' %} | {{ block.super }}{% endblock %}
4
 {% block title %}{% trans 'Password reset' %} | {{ block.super }}{% endblock %}
5
 
5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Password reset' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6
 {% block content %}
16
 {% block content %}
7
 
17
 
8
     <div class="sub-header">
18
     <div class="sub-header">
9
         <h2>{% trans "Password reset" %}</h2>
19
         <h2>{% trans "Password reset" %}</h2>
10
     </div>
20
     </div>
11
 
21
 
12
-    <form action="" method="post" class="form-stacked well">
22
+    <form id="password_reset_form" action="" method="post" class="form-stacked well">
13
     {% csrf_token %}
23
     {% csrf_token %}
14
 
24
 
15
         <p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>
25
         <p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>

+ 4
- 2
oscar/test/helpers.py Datei anzeigen

27
 
27
 
28
 
28
 
29
 def create_product(price=None, title="Dummy title", product_class="Dummy item class",
29
 def create_product(price=None, title="Dummy title", product_class="Dummy item class",
30
-        partner="Dummy partner", partner_sku=None, upc=None, num_in_stock=10, attributes=None):
30
+        partner="Dummy partner", partner_sku=None, upc=None, num_in_stock=10,
31
+        attributes=None, **kwargs):
31
     """
32
     """
32
     Helper method for creating products that are used in tests.
33
     Helper method for creating products that are used in tests.
33
     """
34
     """
34
     ic,_ = ProductClass._default_manager.get_or_create(name=product_class)
35
     ic,_ = ProductClass._default_manager.get_or_create(name=product_class)
35
-    item = Product._default_manager.create(title=title, product_class=ic, upc=upc)
36
+    item = Product._default_manager.create(title=title, product_class=ic,
37
+                                           upc=upc, **kwargs)
36
     if price is not None or partner_sku or num_in_stock is not None:
38
     if price is not None or partner_sku or num_in_stock is not None:
37
         if not partner_sku:
39
         if not partner_sku:
38
             partner_sku = 'sku_%d_%d' % (item.id, random.randint(0, 10000))
40
             partner_sku = 'sku_%d_%d' % (item.id, random.randint(0, 10000))

+ 1
- 1
setup.py Datei anzeigen

25
       packages=find_packages(exclude=["sandbox*", "tests*"]),
25
       packages=find_packages(exclude=["sandbox*", "tests*"]),
26
       include_package_data=True,
26
       include_package_data=True,
27
       install_requires=[
27
       install_requires=[
28
-          'django==1.4',
28
+          'django>=1.4',
29
           'PIL==1.1.7',
29
           'PIL==1.1.7',
30
           'South==0.7.3',
30
           'South==0.7.3',
31
           'django-extra-views==0.2.0',
31
           'django-extra-views==0.2.0',

+ 0
- 0
tests/functional/customer/__init__.py Datei anzeigen


+ 49
- 0
tests/functional/customer/auth_tests.py Datei anzeigen

1
+import re
2
+
3
+from django.contrib.auth import models
4
+from django.core.urlresolvers import reverse
5
+from django.core import mail
6
+
7
+from django_webtest import WebTest
8
+
9
+
10
+class TestAUserWhoseForgottenHerPassword(WebTest):
11
+
12
+    def test_can_reset_her_password(self):
13
+        username, email, password = 'lucy', 'lucy@example.com', 'password'
14
+        models.User.objects.create_user(
15
+            username, email, password
16
+        )
17
+
18
+        # Fill in password reset form
19
+        page = self.app.get(reverse('password-reset'))
20
+        form = page.forms['password_reset_form']
21
+        form['email'] = email
22
+        response = form.submit()
23
+
24
+        # Response should be a redirect and an email should have been sent
25
+        self.assertEqual(302, response.status_code)
26
+        self.assertEqual(1, len(mail.outbox))
27
+
28
+        # Extract URL from email
29
+        email_body = mail.outbox[0].body
30
+        urlfinder = re.compile(r"http://example.com(?P<path>[-A-Za-z0-9\/\._]+)")
31
+        matches = urlfinder.search(email_body, re.MULTILINE)
32
+        self.assertTrue('path' in matches.groupdict())
33
+        path = matches.groupdict()['path']
34
+
35
+        # Reset password and check we get redirect
36
+        reset_page = self.app.get(path)
37
+        form = reset_page.forms['password_reset_form']
38
+        form['new_password1'] = 'monkey'
39
+        form['new_password2'] = 'monkey'
40
+        response = form.submit()
41
+        self.assertEqual(302, response.status_code)
42
+
43
+        # Now attempt to login with new password
44
+        url = reverse('customer:login')
45
+        form = self.app.get(url).forms['login_form']
46
+        form['login-username'] = email
47
+        form['login-password'] = 'monkey'
48
+        response = form.submit('login_submit')
49
+        self.assertEqual(302, response.status_code)

+ 2
- 1
tests/unit/offer/__init__.py Datei anzeigen

6
 
6
 
7
 class OfferTest(TestCase):
7
 class OfferTest(TestCase):
8
     def setUp(self):
8
     def setUp(self):
9
-        self.range = models.Range.objects.create(name="All products range", includes_all_products=True)
9
+        self.range = models.Range.objects.create(
10
+            name="All products range", includes_all_products=True)
10
         self.basket = Basket.objects.create()
11
         self.basket = Basket.objects.create()

+ 167
- 98
tests/unit/offer/benefit_tests.py Datei anzeigen

1
-from decimal import Decimal
1
+from decimal import Decimal as D
2
 
2
 
3
 from django.conf import settings
3
 from django.conf import settings
4
 
4
 
12
 
12
 
13
     def setUp(self):
13
     def setUp(self):
14
         super(PercentageDiscountBenefitTest, self).setUp()
14
         super(PercentageDiscountBenefitTest, self).setUp()
15
-        self.benefit = models.PercentageDiscountBenefit(range=self.range, type="Percentage", value=Decimal('15.00'))
16
-        self.item = create_product(price=Decimal('5.00'))
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)
17
         self.original_offer_rounding_function = getattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION', None)
18
         if self.original_offer_rounding_function is not None:
18
         if self.original_offer_rounding_function is not None:
19
             delattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION')
19
             delattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION')
24
             settings.OSCAR_OFFER_ROUNDING_FUNCTION = self.original_offer_rounding_function
24
             settings.OSCAR_OFFER_ROUNDING_FUNCTION = self.original_offer_rounding_function
25
 
25
 
26
     def test_no_discount_for_empty_basket(self):
26
     def test_no_discount_for_empty_basket(self):
27
-        self.assertEquals(Decimal('0.00'), self.benefit.apply(self.basket))
27
+        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
28
 
28
 
29
     def test_no_discount_for_not_discountable_product(self):
29
     def test_no_discount_for_not_discountable_product(self):
30
         self.item.is_discountable = False
30
         self.item.is_discountable = False
31
         self.item.save()
31
         self.item.save()
32
         self.basket.add_product(self.item, 1)
32
         self.basket.add_product(self.item, 1)
33
-        self.assertEquals(Decimal('0.00'), self.benefit.apply(self.basket))
33
+        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
34
 
34
 
35
     def test_discount_for_single_item_basket(self):
35
     def test_discount_for_single_item_basket(self):
36
         self.basket.add_product(self.item, 1)
36
         self.basket.add_product(self.item, 1)
37
-        self.assertEquals(Decimal('0.15') * Decimal('5.00'), self.benefit.apply(self.basket))
37
+        self.assertEquals(D('0.15') * D('5.00'), self.benefit.apply(self.basket))
38
 
38
 
39
     def test_discount_for_multi_item_basket(self):
39
     def test_discount_for_multi_item_basket(self):
40
         self.basket.add_product(self.item, 3)
40
         self.basket.add_product(self.item, 3)
41
-        self.assertEquals(Decimal('3') * Decimal('0.15') * Decimal('5.00'), self.benefit.apply(self.basket))
41
+        self.assertEquals(D('3') * D('0.15') * D('5.00'), self.benefit.apply(self.basket))
42
 
42
 
43
     def test_discount_for_multi_item_basket_with_max_affected_items_set(self):
43
     def test_discount_for_multi_item_basket_with_max_affected_items_set(self):
44
         self.basket.add_product(self.item, 3)
44
         self.basket.add_product(self.item, 3)
45
         self.benefit.max_affected_items = 1
45
         self.benefit.max_affected_items = 1
46
-        self.assertEquals(Decimal('0.15') * Decimal('5.00'), self.benefit.apply(self.basket))
46
+        self.assertEquals(D('0.15') * D('5.00'), self.benefit.apply(self.basket))
47
 
47
 
48
     def test_discount_can_only_be_applied_once(self):
48
     def test_discount_can_only_be_applied_once(self):
49
         self.basket.add_product(self.item, 3)
49
         self.basket.add_product(self.item, 3)
50
         self.benefit.apply(self.basket)
50
         self.benefit.apply(self.basket)
51
         second_discount = self.benefit.apply(self.basket)
51
         second_discount = self.benefit.apply(self.basket)
52
-        self.assertEquals(Decimal('0.00'), second_discount)
52
+        self.assertEquals(D('0.00'), second_discount)
53
 
53
 
54
     def test_discount_can_be_applied_several_times_when_max_is_set(self):
54
     def test_discount_can_be_applied_several_times_when_max_is_set(self):
55
         self.basket.add_product(self.item, 3)
55
         self.basket.add_product(self.item, 3)
58
             self.assertTrue(self.benefit.apply(self.basket) > 0)
58
             self.assertTrue(self.benefit.apply(self.basket) > 0)
59
 
59
 
60
 
60
 
61
-class AbsoluteDiscountBenefitTest(OfferTest):
61
+class TestAbsoluteDiscount(OfferTest):
62
 
62
 
63
     def setUp(self):
63
     def setUp(self):
64
-        super(AbsoluteDiscountBenefitTest, self).setUp()
64
+        super(TestAbsoluteDiscount, self).setUp()
65
+
65
         self.benefit = models.AbsoluteDiscountBenefit(
66
         self.benefit = models.AbsoluteDiscountBenefit(
66
-            range=self.range, type="Absolute", value=Decimal('10.00'))
67
-        self.item = create_product(price=Decimal('5.00'))
68
-        self.original_offer_rounding_function = getattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION', None)
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)
69
         if self.original_offer_rounding_function is not None:
72
         if self.original_offer_rounding_function is not None:
70
             delattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION')
73
             delattr(settings, 'OSCAR_OFFER_ROUNDING_FUNCTION')
71
 
74
 
72
     def tearDown(self):
75
     def tearDown(self):
73
-        super(AbsoluteDiscountBenefitTest, self).tearDown()
74
         if self.original_offer_rounding_function is not None:
76
         if self.original_offer_rounding_function is not None:
75
             settings.OSCAR_OFFER_ROUNDING_FUNCTION = self.original_offer_rounding_function
77
             settings.OSCAR_OFFER_ROUNDING_FUNCTION = self.original_offer_rounding_function
76
 
78
 
77
-    def test_no_discount_for_empty_basket(self):
78
-        self.assertEquals(Decimal('0.00'), self.benefit.apply(self.basket))
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)
79
 
119
 
80
-    def test_no_discount_for_not_discountable_product(self):
81
-        self.item.is_discountable = False
82
-        self.item.save()
83
-        self.basket.add_product(self.item, 1)
84
-        self.assertEquals(Decimal('0.00'), self.benefit.apply(self.basket))
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)
85
 
127
 
86
-    def test_discount_for_single_item_basket(self):
87
-        self.basket.add_product(self.item, 1)
88
-        self.assertEquals(Decimal('5.00'), self.benefit.apply(self.basket))
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))
89
 
133
 
90
-    def test_discount_for_multi_item_basket(self):
91
-        self.basket.add_product(self.item, 3)
92
-        self.assertEquals(Decimal('10.00'), self.benefit.apply(self.basket))
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)
93
 
137
 
94
-    def test_discount_for_multi_item_basket_with_max_affected_items_set(self):
95
-        self.basket.add_product(self.item, 3)
96
-        self.benefit.max_affected_items = 1
97
-        self.assertEquals(Decimal('5.00'), self.benefit.apply(self.basket))
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))
98
 
141
 
99
-    def test_discount_can_only_be_applied_once(self):
100
-        # Add 3 items to make total 15.00
101
-        self.basket.add_product(self.item, 3)
102
-        first_discount = self.benefit.apply(self.basket)
103
-        self.assertEquals(Decimal('10.00'), first_discount)
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)
104
 
146
 
105
-        second_discount = self.benefit.apply(self.basket)
106
-        self.assertEquals(Decimal('5.00'), second_discount)
147
+        condition = models.ValueCondition(range=rng, type='Value', value=D('5000'))
107
 
148
 
108
-    def test_absolute_does_not_consume_twice(self):
109
-        product = create_product(Decimal('25000'))
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'))
110
         rng = models.Range.objects.create(name='Dummy')
181
         rng = models.Range.objects.create(name='Dummy')
111
         rng.included_products.add(product)
182
         rng.included_products.add(product)
112
-        condition = models.ValueCondition(range=rng, type='Value', value=Decimal('5000'))
183
+
184
+        condition = models.ValueCondition(range=rng, type='Value', value=D('500'))
113
         basket = Basket.objects.create()
185
         basket = Basket.objects.create()
114
-        basket.add_product(product, 5)
115
-        benefit = models.AbsoluteDiscountBenefit(range=rng, type='Absolute', value=Decimal('100'))
186
+        basket.add_product(product, 1)
187
+
188
+        benefit = models.AbsoluteDiscountBenefit(range=rng, type='Absolute', value=D('100'))
189
+
116
         self.assertTrue(condition.is_satisfied(basket))
190
         self.assertTrue(condition.is_satisfied(basket))
117
-        self.assertEquals(Decimal('100'), benefit.apply(basket, condition))
118
-        self.assertEquals(Decimal('100'), benefit.apply(basket, condition))
119
-        self.assertEquals(Decimal('100'), benefit.apply(basket, condition))
120
-        self.assertEquals(Decimal('100'), benefit.apply(basket, condition))
121
-        self.assertEquals(Decimal('100'), benefit.apply(basket, condition))
122
-        self.assertEquals(Decimal('0'), benefit.apply(basket, condition))
191
+        self.assertEquals(D('100'), benefit.apply(basket, condition))
192
+        self.assertEquals(D('100'), basket.all_lines()[0]._discount)
123
 
193
 
124
     def test_discount_is_applied_to_lines(self):
194
     def test_discount_is_applied_to_lines(self):
125
-        condition = models.Condition.objects.create(
195
+        condition = models.CountCondition.objects.create(
126
             range=self.range, type="Count", value=1)
196
             range=self.range, type="Count", value=1)
127
         self.basket.add_product(self.item, 1)
197
         self.basket.add_product(self.item, 1)
128
         self.benefit.apply(self.basket, condition)
198
         self.benefit.apply(self.basket, condition)
129
-
130
         self.assertTrue(self.basket.all_lines()[0].has_discount)
199
         self.assertTrue(self.basket.all_lines()[0].has_discount)
131
 
200
 
132
 
201
 
135
     def setUp(self):
204
     def setUp(self):
136
         super(MultibuyDiscountBenefitTest, self).setUp()
205
         super(MultibuyDiscountBenefitTest, self).setUp()
137
         self.benefit = models.MultibuyDiscountBenefit(range=self.range, type="Multibuy", value=1)
206
         self.benefit = models.MultibuyDiscountBenefit(range=self.range, type="Multibuy", value=1)
138
-        self.item = create_product(price=Decimal('5.00'))
207
+        self.item = create_product(price=D('5.00'))
139
 
208
 
140
     def test_no_discount_for_empty_basket(self):
209
     def test_no_discount_for_empty_basket(self):
141
-        self.assertEquals(Decimal('0.00'), self.benefit.apply(self.basket))
210
+        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
142
 
211
 
143
     def test_discount_for_single_item_basket(self):
212
     def test_discount_for_single_item_basket(self):
144
         self.basket.add_product(self.item, 1)
213
         self.basket.add_product(self.item, 1)
145
-        self.assertEquals(Decimal('5.00'), self.benefit.apply(self.basket))
214
+        self.assertEquals(D('5.00'), self.benefit.apply(self.basket))
146
 
215
 
147
     def test_discount_for_multi_item_basket(self):
216
     def test_discount_for_multi_item_basket(self):
148
         self.basket.add_product(self.item, 3)
217
         self.basket.add_product(self.item, 3)
149
-        self.assertEquals(Decimal('5.00'), self.benefit.apply(self.basket))
218
+        self.assertEquals(D('5.00'), self.benefit.apply(self.basket))
150
 
219
 
151
     def test_no_discount_for_not_discountable_product(self):
220
     def test_no_discount_for_not_discountable_product(self):
152
         self.item.is_discountable = False
221
         self.item.is_discountable = False
153
         self.item.save()
222
         self.item.save()
154
         self.basket.add_product(self.item, 1)
223
         self.basket.add_product(self.item, 1)
155
-        self.assertEquals(Decimal('0.00'), self.benefit.apply(self.basket))
224
+        self.assertEquals(D('0.00'), self.benefit.apply(self.basket))
156
 
225
 
157
     def test_discount_does_not_consume_item_if_in_condition_range(self):
226
     def test_discount_does_not_consume_item_if_in_condition_range(self):
158
         self.basket.add_product(self.item, 1)
227
         self.basket.add_product(self.item, 1)
159
         first_discount = self.benefit.apply(self.basket)
228
         first_discount = self.benefit.apply(self.basket)
160
-        self.assertEquals(Decimal('5.00'), first_discount)
229
+        self.assertEquals(D('5.00'), first_discount)
161
         second_discount = self.benefit.apply(self.basket)
230
         second_discount = self.benefit.apply(self.basket)
162
-        self.assertEquals(Decimal('5.00'), second_discount)
231
+        self.assertEquals(D('5.00'), second_discount)
163
 
232
 
164
     def test_product_does_consume_item_if_not_in_condition_range(self):
233
     def test_product_does_consume_item_if_not_in_condition_range(self):
165
         # Set up condition using a different range from benefit
234
         # Set up condition using a different range from benefit
166
         range = models.Range.objects.create(name="Small range")
235
         range = models.Range.objects.create(name="Small range")
167
-        other_product = create_product(price=Decimal('15.00'))
236
+        other_product = create_product(price=D('15.00'))
168
         range.included_products.add(other_product)
237
         range.included_products.add(other_product)
169
-        cond = models.ValueCondition(range=range, type="Value", value=Decimal('10.00'))
238
+        cond = models.ValueCondition(range=range, type="Value", value=D('10.00'))
170
 
239
 
171
         self.basket.add_product(self.item, 1)
240
         self.basket.add_product(self.item, 1)
172
         self.benefit.apply(self.basket, cond)
241
         self.benefit.apply(self.basket, cond)
175
 
244
 
176
     def test_condition_consumes_most_expensive_lines_first(self):
245
     def test_condition_consumes_most_expensive_lines_first(self):
177
         for i in range(10, 0, -1):
246
         for i in range(10, 0, -1):
178
-            product = create_product(price=Decimal(i), title='%i'%i, upc='upc_%i' % i)
247
+            product = create_product(price=D(i), title='%i'%i, upc='upc_%i' % i)
179
             self.basket.add_product(product, 1)
248
             self.basket.add_product(product, 1)
180
 
249
 
181
         condition = models.CountCondition(range=self.range, type="Count", value=2)
250
         condition = models.CountCondition(range=self.range, type="Count", value=2)
183
         self.assertTrue(condition.is_satisfied(self.basket))
252
         self.assertTrue(condition.is_satisfied(self.basket))
184
         # consume 1 and 10
253
         # consume 1 and 10
185
         first_discount = self.benefit.apply(self.basket, condition=condition)
254
         first_discount = self.benefit.apply(self.basket, condition=condition)
186
-        self.assertEquals(Decimal('1.00'), first_discount)
255
+        self.assertEquals(D('1.00'), first_discount)
187
 
256
 
188
         self.assertTrue(condition.is_satisfied(self.basket))
257
         self.assertTrue(condition.is_satisfied(self.basket))
189
         # consume 2 and 9
258
         # consume 2 and 9
190
         second_discount = self.benefit.apply(self.basket, condition=condition)
259
         second_discount = self.benefit.apply(self.basket, condition=condition)
191
-        self.assertEquals(Decimal('2.00'), second_discount)
260
+        self.assertEquals(D('2.00'), second_discount)
192
 
261
 
193
         self.assertTrue(condition.is_satisfied(self.basket))
262
         self.assertTrue(condition.is_satisfied(self.basket))
194
         # consume 3 and 8
263
         # consume 3 and 8
195
         third_discount = self.benefit.apply(self.basket, condition=condition)
264
         third_discount = self.benefit.apply(self.basket, condition=condition)
196
-        self.assertEquals(Decimal('3.00'), third_discount)
265
+        self.assertEquals(D('3.00'), third_discount)
197
 
266
 
198
         self.assertTrue(condition.is_satisfied(self.basket))
267
         self.assertTrue(condition.is_satisfied(self.basket))
199
         # consume 4 and 7
268
         # consume 4 and 7
200
         fourth_discount = self.benefit.apply(self.basket, condition=condition)
269
         fourth_discount = self.benefit.apply(self.basket, condition=condition)
201
-        self.assertEquals(Decimal('4.00'), fourth_discount)
270
+        self.assertEquals(D('4.00'), fourth_discount)
202
 
271
 
203
         self.assertTrue(condition.is_satisfied(self.basket))
272
         self.assertTrue(condition.is_satisfied(self.basket))
204
         # consume 5 and 6
273
         # consume 5 and 6
205
         fifth_discount = self.benefit.apply(self.basket, condition=condition)
274
         fifth_discount = self.benefit.apply(self.basket, condition=condition)
206
-        self.assertEquals(Decimal('5.00'), fifth_discount)
275
+        self.assertEquals(D('5.00'), fifth_discount)
207
 
276
 
208
         # end of items (one not discounted item in basket)
277
         # end of items (one not discounted item in basket)
209
         self.assertFalse(condition.is_satisfied(self.basket))
278
         self.assertFalse(condition.is_satisfied(self.basket))
210
 
279
 
211
     def test_condition_consumes_most_expensive_lines_first_when_products_are_repeated(self):
280
     def test_condition_consumes_most_expensive_lines_first_when_products_are_repeated(self):
212
         for i in range(5, 0, -1):
281
         for i in range(5, 0, -1):
213
-            product = create_product(price=Decimal(i), title='%i'%i, upc='upc_%i' % i)
282
+            product = create_product(price=D(i), title='%i'%i, upc='upc_%i' % i)
214
             self.basket.add_product(product, 2)
283
             self.basket.add_product(product, 2)
215
 
284
 
216
         condition = models.CountCondition(range=self.range, type="Count", value=2)
285
         condition = models.CountCondition(range=self.range, type="Count", value=2)
219
         self.assertTrue(condition.is_satisfied(self.basket))
288
         self.assertTrue(condition.is_satisfied(self.basket))
220
         # consume 1 and 5
289
         # consume 1 and 5
221
         first_discount = self.benefit.apply(self.basket, condition=condition)
290
         first_discount = self.benefit.apply(self.basket, condition=condition)
222
-        self.assertEquals(Decimal('1.00'), first_discount)
291
+        self.assertEquals(D('1.00'), first_discount)
223
 
292
 
224
         self.assertTrue(condition.is_satisfied(self.basket))
293
         self.assertTrue(condition.is_satisfied(self.basket))
225
         # consume 1 and 5
294
         # consume 1 and 5
226
         second_discount = self.benefit.apply(self.basket, condition=condition)
295
         second_discount = self.benefit.apply(self.basket, condition=condition)
227
-        self.assertEquals(Decimal('1.00'), second_discount)
296
+        self.assertEquals(D('1.00'), second_discount)
228
 
297
 
229
         self.assertTrue(condition.is_satisfied(self.basket))
298
         self.assertTrue(condition.is_satisfied(self.basket))
230
         # consume 2 and 4
299
         # consume 2 and 4
231
         third_discount = self.benefit.apply(self.basket, condition=condition)
300
         third_discount = self.benefit.apply(self.basket, condition=condition)
232
-        self.assertEquals(Decimal('2.00'), third_discount)
301
+        self.assertEquals(D('2.00'), third_discount)
233
 
302
 
234
         self.assertTrue(condition.is_satisfied(self.basket))
303
         self.assertTrue(condition.is_satisfied(self.basket))
235
         # consume 2 and 4
304
         # consume 2 and 4
236
         third_discount = self.benefit.apply(self.basket, condition=condition)
305
         third_discount = self.benefit.apply(self.basket, condition=condition)
237
-        self.assertEquals(Decimal('2.00'), third_discount)
306
+        self.assertEquals(D('2.00'), third_discount)
238
 
307
 
239
         self.assertTrue(condition.is_satisfied(self.basket))
308
         self.assertTrue(condition.is_satisfied(self.basket))
240
         # consume 3 and 3
309
         # consume 3 and 3
241
         third_discount = self.benefit.apply(self.basket, condition=condition)
310
         third_discount = self.benefit.apply(self.basket, condition=condition)
242
-        self.assertEquals(Decimal('3.00'), third_discount)
311
+        self.assertEquals(D('3.00'), third_discount)
243
 
312
 
244
         # end of items (one not discounted item in basket)
313
         # end of items (one not discounted item in basket)
245
         self.assertFalse(condition.is_satisfied(self.basket))
314
         self.assertFalse(condition.is_satisfied(self.basket))
255
 
324
 
256
     def setUp(self):
325
     def setUp(self):
257
         super(FixedPriceBenefitTest, self).setUp()
326
         super(FixedPriceBenefitTest, self).setUp()
258
-        self.benefit = models.FixedPriceBenefit(range=self.range, type="FixedPrice", value=Decimal('10.00'))
327
+        self.benefit = models.FixedPriceBenefit(range=self.range, type="FixedPrice", value=D('10.00'))
259
 
328
 
260
     def test_correct_discount_for_count_condition(self):
329
     def test_correct_discount_for_count_condition(self):
261
-        products = [create_product(Decimal('7.00')),
262
-                    create_product(Decimal('8.00')),
263
-                    create_product(Decimal('12.00'))]
330
+        products = [create_product(D('7.00')),
331
+                    create_product(D('8.00')),
332
+                    create_product(D('12.00'))]
264
 
333
 
265
         # Create range that includes the products
334
         # Create range that includes the products
266
         range = models.Range.objects.create(name="Dummy range")
335
         range = models.Range.objects.create(name="Dummy range")
272
         basket = Basket.objects.create()
341
         basket = Basket.objects.create()
273
         [basket.add_product(p, 2) for p in products]
342
         [basket.add_product(p, 2) for p in products]
274
 
343
 
275
-        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=Decimal('20.00'))
276
-        self.assertEquals(Decimal('2.00'), benefit.apply(basket, condition))
277
-        self.assertEquals(Decimal('12.00'), benefit.apply(basket, condition))
278
-        self.assertEquals(Decimal('0.00'), benefit.apply(basket, condition))
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))
279
 
348
 
280
     def test_correct_discount_is_returned(self):
349
     def test_correct_discount_is_returned(self):
281
-        products = [create_product(Decimal('8.00')), create_product(Decimal('4.00'))]
350
+        products = [create_product(D('8.00')), create_product(D('4.00'))]
282
         range = models.Range.objects.create(name="Dummy range")
351
         range = models.Range.objects.create(name="Dummy range")
283
         for product in products:
352
         for product in products:
284
             range.included_products.add(product)
353
             range.included_products.add(product)
289
 
358
 
290
         condition = models.CoverageCondition(range=range, type="Coverage", value=2)
359
         condition = models.CoverageCondition(range=range, type="Coverage", value=2)
291
         discount = self.benefit.apply(basket, condition)
360
         discount = self.benefit.apply(basket, condition)
292
-        self.assertEquals(Decimal('2.00'), discount)
361
+        self.assertEquals(D('2.00'), discount)
293
 
362
 
294
     def test_no_discount_when_product_not_discountable(self):
363
     def test_no_discount_when_product_not_discountable(self):
295
-        product = create_product(Decimal('18.00'))
364
+        product = create_product(D('18.00'))
296
         product.is_discountable = False
365
         product.is_discountable = False
297
         product.save()
366
         product.save()
298
 
367
 
304
 
373
 
305
         condition = models.CoverageCondition(range=product_range, type="Coverage", value=1)
374
         condition = models.CoverageCondition(range=product_range, type="Coverage", value=1)
306
         discount = self.benefit.apply(basket, condition)
375
         discount = self.benefit.apply(basket, condition)
307
-        self.assertEquals(Decimal('0.00'), discount)
376
+        self.assertEquals(D('0.00'), discount)
308
 
377
 
309
     def test_no_discount_is_returned_when_value_is_greater_than_product_total(self):
378
     def test_no_discount_is_returned_when_value_is_greater_than_product_total(self):
310
-        products = [create_product(Decimal('4.00')), create_product(Decimal('4.00'))]
379
+        products = [create_product(D('4.00')), create_product(D('4.00'))]
311
         range = models.Range.objects.create(name="Dummy range")
380
         range = models.Range.objects.create(name="Dummy range")
312
         for product in products:
381
         for product in products:
313
             range.included_products.add(product)
382
             range.included_products.add(product)
318
 
387
 
319
         condition = models.CoverageCondition(range=range, type="Coverage", value=2)
388
         condition = models.CoverageCondition(range=range, type="Coverage", value=2)
320
         discount = self.benefit.apply(basket, condition)
389
         discount = self.benefit.apply(basket, condition)
321
-        self.assertEquals(Decimal('0.00'), discount)
390
+        self.assertEquals(D('0.00'), discount)
322
 
391
 
323
     def test_discount_when_more_products_than_required(self):
392
     def test_discount_when_more_products_than_required(self):
324
-        products = [create_product(Decimal('4.00')),
325
-                    create_product(Decimal('8.00')),
326
-                    create_product(Decimal('12.00'))]
393
+        products = [create_product(D('4.00')),
394
+                    create_product(D('8.00')),
395
+                    create_product(D('12.00'))]
327
 
396
 
328
         # Create range that includes the products
397
         # Create range that includes the products
329
         range = models.Range.objects.create(name="Dummy range")
398
         range = models.Range.objects.create(name="Dummy range")
336
         [basket.add_product(p) for p in products]
405
         [basket.add_product(p) for p in products]
337
         basket.add_product(products[0])
406
         basket.add_product(products[0])
338
 
407
 
339
-        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=Decimal('20.00'))
408
+        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=D('20.00'))
340
         discount = benefit.apply(basket, condition)
409
         discount = benefit.apply(basket, condition)
341
-        self.assertEquals(Decimal('4.00'), discount)
410
+        self.assertEquals(D('4.00'), discount)
342
 
411
 
343
     def test_discount_when_applied_twice(self):
412
     def test_discount_when_applied_twice(self):
344
-        products = [create_product(Decimal('4.00')),
345
-                    create_product(Decimal('8.00')),
346
-                    create_product(Decimal('12.00'))]
413
+        products = [create_product(D('4.00')),
414
+                    create_product(D('8.00')),
415
+                    create_product(D('12.00'))]
347
 
416
 
348
         # Create range that includes the products
417
         # Create range that includes the products
349
         range = models.Range.objects.create(name="Dummy range")
418
         range = models.Range.objects.create(name="Dummy range")
355
         basket = Basket.objects.create()
424
         basket = Basket.objects.create()
356
         [basket.add_product(p, 2) for p in products]
425
         [basket.add_product(p, 2) for p in products]
357
 
426
 
358
-        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=Decimal('20.00'))
427
+        benefit = models.FixedPriceBenefit(range=range, type="FixedPrice", value=D('20.00'))
359
         first_discount = benefit.apply(basket, condition)
428
         first_discount = benefit.apply(basket, condition)
360
-        self.assertEquals(Decimal('4.00'), first_discount)
429
+        self.assertEquals(D('4.00'), first_discount)
361
         second_discount = benefit.apply(basket, condition)
430
         second_discount = benefit.apply(basket, condition)
362
-        self.assertEquals(Decimal('4.00'), second_discount)
431
+        self.assertEquals(D('4.00'), second_discount)

Laden…
Abbrechen
Speichern