diff --git a/addons/pos_sale/models/__init__.py b/addons/pos_sale/models/__init__.py
index b23ba5d574e4538c0d75a74267177ce3435c1962..5e5b400d6daeeccbb6f91c12cbaf25c1b95ece9b 100644
--- a/addons/pos_sale/models/__init__.py
+++ b/addons/pos_sale/models/__init__.py
@@ -6,3 +6,4 @@ from . import pos_order
 from . import crm_team
 from . import pos_session
 from . import sale_order
+from . import stock_picking
diff --git a/addons/pos_sale/models/stock_picking.py b/addons/pos_sale/models/stock_picking.py
new file mode 100644
index 0000000000000000000000000000000000000000..999f1a955fd60e1b3a240a3313cff014969cfe07
--- /dev/null
+++ b/addons/pos_sale/models/stock_picking.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models
+
+
+class StockPicking(models.Model):
+    _inherit = 'stock.picking'
+
+    def _create_move_from_pos_order_lines(self, lines):
+        lines_to_unreserve = self.env['pos.order.line']
+        for line in lines:
+            if line.order_id.to_ship:
+                continue
+            if any(wh != line.order_id.config_id.warehouse_id for wh in line.sale_order_line_id.move_ids.location_id.warehouse_id):
+                continue
+            lines_to_unreserve |= line
+        lines_to_unreserve.sale_order_line_id.move_ids.filtered(lambda ml: ml.state not in ['cancel', 'done'])._do_unreserve()
+        return super()._create_move_from_pos_order_lines(lines)
diff --git a/addons/pos_sale/static/tests/tours/pos_sale_tours.js b/addons/pos_sale/static/tests/tours/pos_sale_tours.js
index a6f3355812e3219fc1bc56bcc37fb90be79c1ee6..4957ecd4ae49e4445a6e23a3beee3144db9137a7 100644
--- a/addons/pos_sale/static/tests/tours/pos_sale_tours.js
+++ b/addons/pos_sale/static/tests/tours/pos_sale_tours.js
@@ -52,4 +52,17 @@ odoo.define('pos_sale.tour', function (require) {
     ProductScreen.check.totalAmountIs(100);
 
     Tour.register('PosSettleOrderWithPromotions', { test: true, url: '/pos/ui' }, getSteps());
+
+    startSteps();
+
+    ProductScreen.do.confirmOpeningPopup();
+    ProductScreen.do.clickQuotationButton();
+    ProductScreen.do.selectFirstOrder();
+    ProductScreen.check.totalAmountIs(40);
+    ProductScreen.do.clickPayButton();
+    PaymentScreen.do.clickPaymentMethod('Bank');
+    PaymentScreen.do.clickValidate();
+    Chrome.do.clickTicketButton();
+
+    Tour.register('PosSettleOrderRealTime', { test: true, url: '/pos/ui' }, getSteps());
 });
diff --git a/addons/pos_sale/tests/test_pos_sale_flow.py b/addons/pos_sale/tests/test_pos_sale_flow.py
index 310f2bc79122394495f728522e3079a1dae077c3..0efaf216865cdd8ff6838b5eb4557113eb01e935 100644
--- a/addons/pos_sale/tests/test_pos_sale_flow.py
+++ b/addons/pos_sale/tests/test_pos_sale_flow.py
@@ -166,3 +166,76 @@ class TestPoSSale(TestPointOfSaleHttpCommon):
         })
         self.main_pos_config.open_session_cb()
         self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderWithPromotions', login="accountman")
+
+    def test_settle_order_unreserve_order_lines(self):
+        #create a product category that use the closest location for the removal strategy
+        self.removal_strategy = self.env['product.removal'].search([('method', '=', 'closest')], limit=1)
+        self.product_category = self.env['product.category'].create({
+            'name': 'Product Category',
+            'removal_strategy_id': self.removal_strategy.id,
+        })
+
+        self.product = self.env['product.product'].create({
+            'name': 'Product',
+            'available_in_pos': True,
+            'type': 'product',
+            'lst_price': 10.0,
+            'taxes_id': False,
+            'categ_id': self.product_category.id,
+        })
+
+        #create 2 stock location Shelf 1 and Shelf 2
+        self.warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
+        self.shelf_1 = self.env['stock.location'].create({
+            'name': 'Shelf 1',
+            'usage': 'internal',
+            'location_id': self.warehouse.lot_stock_id.id,
+        })
+        self.shelf_2 = self.env['stock.location'].create({
+            'name': 'Shelf 2',
+            'usage': 'internal',
+            'location_id': self.warehouse.lot_stock_id.id,
+        })
+
+        quants = self.env['stock.quant'].with_context(inventory_mode=True).create({
+            'product_id': self.product.id,
+            'inventory_quantity': 2,
+            'location_id': self.shelf_1.id,
+        })
+        quants |= self.env['stock.quant'].with_context(inventory_mode=True).create({
+            'product_id': self.product.id,
+            'inventory_quantity': 5,
+            'location_id': self.shelf_2.id,
+        })
+        quants.action_apply_inventory()
+
+        sale_order = self.env['sale.order'].create({
+            'partner_id': self.env.ref('base.res_partner_2').id,
+            'order_line': [(0, 0, {
+                'product_id': self.product.id,
+                'name': self.product.name,
+                'product_uom_qty': 4,
+                'price_unit': self.product.lst_price,
+            })],
+        })
+        sale_order.action_confirm()
+
+        self.assertEqual(sale_order.order_line.move_ids.move_line_ids[0].product_qty, 2)
+        self.assertEqual(sale_order.order_line.move_ids.move_line_ids[0].location_id.id, self.shelf_1.id)
+        self.assertEqual(sale_order.order_line.move_ids.move_line_ids[1].product_qty, 2)
+        self.assertEqual(sale_order.order_line.move_ids.move_line_ids[1].location_id.id, self.shelf_2.id)
+
+        self.config = self.env['res.config.settings'].create({
+            'update_stock_quantities': 'real',
+        })
+        self.config.execute()
+
+        self.main_pos_config.open_session_cb()
+        self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrderRealTime', login="accountman")
+
+        pos_order = self.env['pos.order'].search([], order='id desc', limit=1)
+        self.assertEqual(pos_order.picking_ids.move_line_ids[0].qty_done, 2)
+        self.assertEqual(pos_order.picking_ids.move_line_ids[0].location_id.id, self.shelf_1.id)
+        self.assertEqual(pos_order.picking_ids.move_line_ids[1].qty_done, 2)
+        self.assertEqual(pos_order.picking_ids.move_line_ids[1].location_id.id, self.shelf_2.id)
+        self.assertEqual(sale_order.order_line.move_ids.move_lines_count, 0)