From 97c7d387a7aea7f570ba3949d9d22ef64cd02c3a Mon Sep 17 00:00:00 2001 From: roen-odoo Date: Tue, 25 Jul 2023 15:13:20 +0000 Subject: [PATCH] [FIX] pos_sale: correctly cancel all moves with 0 qty Current behavior: When you settle an order in the PoS and completely validate it, the remaining moves from the original sales should be cancelled. However, it was not the case because we were not adding all the picking in the `waiting_picking_ids` list. And so when we were checking this list we were not cancelling all the moves. Steps to reproduce: - Setup multi-step routes (Inventory > Settings > Multi-Step Routes) - Change the configuration of the warehouse to use the multi-step routes - Create a sale order for any product and confirm it - Open the PoS, and settle the order you just created - Validate the order - Go back to the sale order, and check the state of the delivery - Only one picking has been cancelled opw-3390529 closes odoo/odoo#133547 X-original-commit: c57b8286e3dedb75db68f27fc514224f6ba8d1c1 Signed-off-by: Joseph Caburnay (jcb) Signed-off-by: Robin Engels (roen) --- addons/pos_sale/models/pos_order.py | 1 + .../static/tests/tours/PosSaleTour.js | 23 ++++++++++++ addons/pos_sale/tests/test_pos_sale_flow.py | 36 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/addons/pos_sale/models/pos_order.py b/addons/pos_sale/models/pos_order.py index a341bba2407..23cc48cc983 100644 --- a/addons/pos_sale/models/pos_order.py +++ b/addons/pos_sale/models/pos_order.py @@ -89,6 +89,7 @@ class PosOrder(models.Model): #If the product is delivered with more than one step, we need to update the quantity of the other steps for move in so_line_stock_move_ids.filtered(lambda m: m.state in ['waiting', 'confirmed'] and m.product_id == stock_move.product_id): move.product_uom_qty = stock_move.product_uom_qty + waiting_picking_ids.add(move.picking_id.id) waiting_picking_ids.add(picking.id) def is_product_uom_qty_zero(move): diff --git a/addons/pos_sale/static/tests/tours/PosSaleTour.js b/addons/pos_sale/static/tests/tours/PosSaleTour.js index 0bab1803ba8..5947dde96ab 100644 --- a/addons/pos_sale/static/tests/tours/PosSaleTour.js +++ b/addons/pos_sale/static/tests/tours/PosSaleTour.js @@ -138,3 +138,26 @@ registry return getSteps(); } }); + +registry + .category("web_tour.tours") + .add('PosSettleOrder3', { + test: true, + url: '/pos/ui', + steps: () => { + startSteps(); + + ProductScreen.do.confirmOpeningPopup(); + ProductScreen.do.clickQuotationButton(); + ProductScreen.do.selectFirstOrder(); + ProductScreen.do.clickOrderline("Product A", "1"); + ProductScreen.check.selectedOrderlineHas('Product A', '1.00'); + ProductScreen.do.clickPayButton(); + PaymentScreen.do.clickPaymentMethod('Bank'); + PaymentScreen.check.remainingIs('0.0'); + PaymentScreen.do.clickValidate(); + ReceiptScreen.check.isShown(); + + return getSteps(); + } + }); diff --git a/addons/pos_sale/tests/test_pos_sale_flow.py b/addons/pos_sale/tests/test_pos_sale_flow.py index 10aa5cbf41e..ded2aa390ae 100644 --- a/addons/pos_sale/tests/test_pos_sale_flow.py +++ b/addons/pos_sale/tests/test_pos_sale_flow.py @@ -255,3 +255,39 @@ class TestPoSSale(TestPointOfSaleHttpCommon): 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) + + def test_settle_order_with_multistep_delivery(self): + """This test create an order and settle it in the PoS. It also uses multistep delivery + and we need to make sure that all the picking are cancelled if the order is fully delivered. + """ + + #get the warehouse + warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1) + warehouse.delivery_steps = 'pick_pack_ship' + + product_a = self.env['product.product'].create({ + 'name': 'Product A', + 'available_in_pos': True, + 'type': 'product', + 'lst_price': 10.0, + }) + #create a sale order with 2 lines + sale_order = self.env['sale.order'].create({ + 'partner_id': self.env.ref('base.res_partner_2').id, + 'order_line': [(0, 0, { + 'product_id': product_a.id, + 'name': product_a.name, + 'product_uom_qty': 1, + 'product_uom': product_a.uom_id.id, + 'price_unit': product_a.lst_price, + })], + }) + sale_order.action_confirm() + + self.assertEqual(sale_order.order_line[0].qty_delivered, 0) + + self.main_pos_config.open_ui() + self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PosSettleOrder3', login="accountman") + + self.assertEqual(sale_order.order_line[0].qty_delivered, 1) + self.assertEqual(sale_order.picking_ids.mapped('state'), ['cancel', 'cancel', 'cancel'])