diff --git a/addons/stock/models/stock_location.py b/addons/stock/models/stock_location.py
index 38847795155c042af55f9d7adbf44607353b8bc0..8550b1c34b7163dc1a54a777820dd08a19c8d58a 100644
--- a/addons/stock/models/stock_location.py
+++ b/addons/stock/models/stock_location.py
@@ -407,6 +407,12 @@ class Location(models.Model):
                 product = product or self._context.get('products')
                 if (positive_quant and positive_quant.product_id != product) or len(product) > 1:
                     return False
+                if self.env['stock.move.line'].search([
+                    ('product_id', '!=', product.id),
+                    ('state', 'not in', ('done', 'cancel')),
+                    ('location_dest_id', '=', self.id),
+                ], limit=1):
+                    return False
         return True
 
 
diff --git a/addons/stock/tests/test_packing.py b/addons/stock/tests/test_packing.py
index 86a016e97d2c2cda39ee97f6ad8ac27ec98b72f1..6b0e6a785da226b718c0f2182f3230065de6fdb3 100644
--- a/addons/stock/tests/test_packing.py
+++ b/addons/stock/tests/test_packing.py
@@ -1229,13 +1229,17 @@ class TestPacking(TestPackingCommon):
     def test_pack_in_receipt_two_step_multi_putaway_04(self):
         """
         Create a putaway rules for package type T and storage category SC. SC
-        only allows same products and has a maximum of 2 x T. Two SC locations
-        L1 and L2.
+        only allows same products and has a maximum of 2 x T. Four SC locations
+        L1, L2, L3 and L4.
         First, move a package that contains two different products: should not
         redirect to L1/L2 because of the "same products" contraint.
-        Then, add one T-package (with product P) at L1 and move 2 T-packages
-        (both with product P): one should be redirected to L1 and the second one
-        to L2
+        Then, add one T-package (with product P01) at L1 and move 2 T-packages
+        (both with product P01): one should be redirected to L1 and the second
+        one to L2
+        Finally, move 3 T-packages (two with 1xP01, one with 1xP02): one P01
+        should be redirected to L2 and the second one to L3 (because of capacity
+        constraint), then P02 should be redirected to L4 (because of "same
+        product" policy)
         """
         self.warehouse.reception_steps = "two_steps"
         supplier_location = self.env.ref('stock.stock_location_suppliers')
@@ -1255,12 +1259,12 @@ class TestPacking(TestPackingCommon):
             })],
         })
 
-        loc01, loc02 = self.env['stock.location'].create([{
-            'name': n,
+        loc01, loc02, loc03, loc04 = self.env['stock.location'].create([{
+            'name': 'loc 0%d' % i,
             'usage': 'internal',
             'location_id': self.stock_location.id,
             'storage_category_id': storage_category.id,
-        } for n in ('loc01', 'loc02')])
+        } for i in range(1, 5)])
 
         self.env['stock.putaway.rule'].create({
             'location_in_id': self.stock_location.id,
@@ -1288,10 +1292,11 @@ class TestPacking(TestPackingCommon):
         moves.move_line_ids.qty_done = 1
         moves.move_line_ids.result_package_id = self.env['stock.quant.package'].create({'package_type_id': package_type.id})
         receipt.button_validate()
-        dest_moves = moves.move_dest_ids
-        self.assertEqual(dest_moves.move_line_ids.location_dest_id, self.stock_location,
+        internal_picking = moves.move_dest_ids.picking_id
+        self.assertEqual(internal_picking.move_line_ids.location_dest_id, self.stock_location,
                          'Storage location only accepts one same product. Here the package contains two different '
                          'products so it should not be redirected.')
+        internal_picking.action_cancel()
 
         # Second test part
         package = self.env['stock.quant.package'].create({'package_type_id': package_type.id})
@@ -1325,9 +1330,53 @@ class TestPacking(TestPackingCommon):
         } for _ in range(2)])
         receipt.button_validate()
 
-        self.assertEqual(receipt.move_ids.move_dest_ids.move_line_ids.location_dest_id, loc01 | loc02,
+        internal_transfer = receipt.move_ids.move_dest_ids.picking_id
+        self.assertEqual(internal_transfer.move_line_ids.location_dest_id, loc01 | loc02,
                          'There is already one package at L1, so the first SML should be redirected to L1 '
                          'and the second one to L2')
+        internal_transfer.move_line_ids.qty_done = 1
+        internal_transfer.button_validate()
+
+        # Third part (move 3 packages, 2 x P01 and 1 x P02)
+        receipt = self.env['stock.picking'].create({
+            'picking_type_id': self.warehouse.in_type_id.id,
+            'location_id': supplier_location.id,
+            'location_dest_id': input_location.id,
+            'move_ids': [(0, 0, {
+                'name': product.name,
+                'location_id': supplier_location.id,
+                'location_dest_id': input_location.id,
+                'product_id': product.id,
+                'product_uom': product.uom_id.id,
+                'product_uom_qty': qty,
+            }) for qty, product in [(2.0, self.productA), (1.0, self.productB)]],
+        })
+        receipt.action_confirm()
+
+        receipt.do_unreserve()
+        moves = receipt.move_ids
+        self.env['stock.move.line'].create([{
+            'move_id': move.id,
+            'qty_done': 1,
+            'product_id': product.id,
+            'product_uom_id': product.uom_id.id,
+            'location_id': supplier_location.id,
+            'location_dest_id': input_location.id,
+            'result_package_id': self.env['stock.quant.package'].create({'package_type_id': package_type.id}).id,
+            'picking_id': receipt.id,
+        } for product, move in [
+            (self.productA, moves[0]),
+            (self.productA, moves[0]),
+            (self.productB, moves[1]),
+        ]])
+        receipt.button_validate()
+
+        internal_transfer = receipt.move_ids.move_dest_ids.picking_id
+        self.assertRecordValues(internal_transfer.move_line_ids, [
+            {'product_id': self.productA.id, 'reserved_uom_qty': 1.0, 'location_dest_id': loc02.id},
+            {'product_id': self.productA.id, 'reserved_uom_qty': 1.0, 'location_dest_id': loc03.id},
+            {'product_id': self.productB.id, 'reserved_uom_qty': 1.0, 'location_dest_id': loc04.id},
+        ])
 
     def test_rounding_and_reserved_qty(self):
         """