Repository: saleor/saleor

Issue:
Allocated line items should be computed while changing line quantity
A user makes an order for 5 items of the same product. 
Now we have this stock situation:  Quantity: 6,  Allocated:5

Go to the dashboard order page.
If we try to change the line quantity to 2-6 inside the dashboard we'll get an error: "Only 1 remaining in stock.".
The allocated line items should be added to the available stock.



Discussion:

Resolving patch:
diff --git a/saleor/dashboard/order/forms.py b/saleor/dashboard/order/forms.py
--- a/saleor/dashboard/order/forms.py
+++ b/saleor/dashboard/order/forms.py
@@ -149,10 +149,11 @@ def __init__(self, *args, **kwargs):
 
     def clean_quantity(self):
         quantity = self.cleaned_data['quantity']
+        delta = quantity - self.initial_quantity
         variant = get_object_or_404(
             ProductVariant, sku=self.instance.product_sku)
         try:
-            variant.check_quantity(quantity)
+            variant.check_quantity(delta)
         except InsufficientStock as e:
             raise forms.ValidationError(
                 _('Only %(remaining)d remaining in stock.') % {


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -9,6 +9,7 @@
 from saleor.cart.models import Cart
 from saleor.checkout.core import Checkout
 from saleor.discount.models import Voucher
+from saleor.order.models import Order
 from saleor.product.models import Product, ProductVariant, Stock
 from saleor.shipping.models import ShippingMethod
 from saleor.userprofile.models import Address, User
@@ -40,6 +41,11 @@ def request_cart_with_item(product_in_stock, request_cart):
     return request_cart
 
 
+@pytest.fixture
+def order(billing_address):
+    return Order.objects.create(billing_address=billing_address)
+
+
 @pytest.fixture()
 def admin_user(db):  # pylint: disable=W0613
     """A Django admin user.
diff --git a/tests/test_order.py b/tests/test_order.py
--- a/tests/test_order.py
+++ b/tests/test_order.py
@@ -1,6 +1,7 @@
 from prices import Price
 
 from saleor.cart.models import Cart
+from saleor.dashboard.order.forms import ChangeQuantityForm
 from saleor.order import models
 
 
@@ -35,3 +36,34 @@ def test_stock_allocation(billing_address, product_in_stock):
     order_line = delivery_group.items.get()
     stock = order_line.stock
     assert stock.quantity_allocated == 2
+
+
+def test_dashboard_change_quantity_form(request_cart_with_item, order):
+    cart = request_cart_with_item
+    group = models.DeliveryGroup.objects.create(order=order)
+    group.add_items_from_partition(cart)
+    order_line = group.items.get()
+
+    # Check available quantity validation
+    form = ChangeQuantityForm({'quantity': 9999},
+                              instance=order_line)
+    assert not form.is_valid()
+    assert group.items.get().stock.quantity_allocated == 1
+    # Save same quantity
+    form = ChangeQuantityForm({'quantity': 1},
+                              instance=order_line)
+    assert form.is_valid()
+    form.save()
+    assert group.items.get().stock.quantity_allocated == 1
+    # Increase quantity
+    form = ChangeQuantityForm({'quantity': 2},
+                              instance=order_line)
+    assert form.is_valid()
+    form.save()
+    assert group.items.get().stock.quantity_allocated == 2
+    # Decrease quantity
+    form = ChangeQuantityForm({'quantity': 1},
+                              instance=order_line)
+    assert form.is_valid()
+    form.save()
+    assert group.items.get().stock.quantity_allocated == 1