Repository: saleor/saleor

Issue:
Sale prices are not used in checkout 
Checkout skips sales for a product and uses regular prices.


Discussion:

Resolving patch:
diff --git a/saleor/cart/utils.py b/saleor/cart/utils.py
--- a/saleor/cart/utils.py
+++ b/saleor/cart/utils.py
@@ -137,6 +137,7 @@ def get_cart_from_request(request, cart_queryset=Cart.objects.all()):
     :type request: django.http.HttpRequest
     :rtype: Cart
     """
+    discounts = request.discounts
     if request.user.is_authenticated():
         cart = get_user_cart(request.user, cart_queryset)
         user = request.user
@@ -145,9 +146,10 @@ def get_cart_from_request(request, cart_queryset=Cart.objects.all()):
         cart = get_anonymous_cart_from_token(token, cart_queryset)
         user = None
     if cart is not None:
+        cart.discounts = discounts
         return cart
     else:
-        return Cart(user=user)
+        return Cart(user=user, discounts=discounts)
 
 
 def get_or_create_db_cart(cart_queryset=Cart.objects.all()):


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -9,7 +9,7 @@
 from saleor.cart import utils
 from saleor.cart.models import Cart
 from saleor.checkout.core import Checkout
-from saleor.discount.models import Voucher
+from saleor.discount.models import Voucher, Sale
 from saleor.order.models import Order
 from saleor.product.models import (AttributeChoiceValue, Category, Product,
                                    ProductAttribute, ProductClass,
@@ -34,6 +34,7 @@ def request_cart(cart, monkeypatch):
     monkeypatch.setattr(
         utils, 'get_cart_from_request',
         lambda request, cart_queryset=None: cart)
+    cart.discounts = Sale.objects.all()
     return cart
 
 
@@ -151,3 +152,10 @@ def anonymous_checkout():
 @pytest.fixture
 def voucher(db):  # pylint: disable=W0613
     return Voucher.objects.create(code='mirumee', discount_value=20)
+
+
+@pytest.fixture()
+def sale(db, default_category):
+    sale = Sale.objects.create(name="Sale", value=5)
+    sale.categories.add(default_category)
+    return sale
diff --git a/tests/test_cart.py b/tests/test_cart.py
--- a/tests/test_cart.py
+++ b/tests/test_cart.py
@@ -9,9 +9,12 @@
 from django.core.exceptions import ObjectDoesNotExist
 from mock import MagicMock, Mock
 from satchless.item import InsufficientStock
+from prices import Price
+
 
 from saleor.cart import forms, utils
 from saleor.cart.models import Cart
+from saleor.discount.models import Sale
 
 
 @pytest.fixture()
@@ -22,6 +25,7 @@ def create_request(user=None, token=None):
             request.user = AnonymousUser()
         else:
             request.user = user
+        request.discounts = Sale.objects.all()
         monkeypatch.setattr(request, 'get_signed_cookie',
                             Mock(return_value=token))
         return request
@@ -181,6 +185,8 @@ def test_get_cart_from_request(monkeypatch, customer_user,
     mock_get_for_user.assert_called_once_with(customer_user, queryset)
     assert returned_cart == user_cart
 
+    assert list(returned_cart.discounts) == list(request.discounts)
+
     mock_get_for_user = Mock(return_value=None)
     monkeypatch.setattr('saleor.cart.utils.get_user_cart',
                         mock_get_for_user)
@@ -443,10 +449,13 @@ def test_view_empty_cart(client, request_cart):
     assert response.status_code == 200
 
 
-def test_view_cart(client, product_in_stock, request_cart):
+def test_view_cart(client, sale, product_in_stock, request_cart):
     variant = product_in_stock.variants.get()
     request_cart.add(variant, 1)
     response = client.get('/cart/')
+    response_cart_line = response.context[0]['cart_lines'][0]
+    cart_line = request_cart.lines.first()
+    assert not response_cart_line['get_total'] == cart_line.get_total()
     assert response.status_code == 200
 
 
@@ -524,3 +533,11 @@ def test_cart_summary_page_empty_cart(client, request_cart):
     assert response.status_code == 200
     content = response.content.decode('utf-8')
     assert json.loads(content) == {}
+
+
+def test_total_with_discount(client, sale, request_cart, product_in_stock):
+    sales = Sale.objects.all()
+    variant = product_in_stock.variants.get()
+    request_cart.add(variant, 1)
+    line = request_cart.lines.first()
+    assert line.get_total(discounts=sales) == Price(currency="USD", net=5)
diff --git a/tests/test_checkout.py b/tests/test_checkout.py
--- a/tests/test_checkout.py
+++ b/tests/test_checkout.py
@@ -184,3 +184,10 @@ def test_index_view(cart, status_code, url, rf):
     response = views.index_view(request, checkout, checkout.cart)
     assert response.status_code == status_code
     assert response.url == url
+
+
+def test_checkout_discount(request_cart, sale, product_in_stock):
+    variant = product_in_stock.variants.get()
+    request_cart.add(variant, 1)
+    checkout = Checkout(request_cart, AnonymousUser(), 'tracking_code')
+    assert checkout.get_total() == Price(currency="USD", net=5)
diff --git a/tests/test_order.py b/tests/test_order.py
--- a/tests/test_order.py
+++ b/tests/test_order.py
@@ -67,3 +67,11 @@ def test_dashboard_change_quantity_form(request_cart_with_item, order):
     assert form.is_valid()
     form.save()
     assert group.items.get().stock.quantity_allocated == 1
+
+
+def test_order_discount(sale, order, request_cart_with_item):
+    cart = request_cart_with_item
+    group = models.DeliveryGroup.objects.create(order=order)
+    group.add_items_from_partition(cart.lines.all(), discounts=cart.discounts)
+    item = group.items.first()
+    assert item.get_price_per_item() == Price(currency="USD", net=5)