From d6ecbf36a02705c7ce49aa378b13984043380bce Mon Sep 17 00:00:00 2001 From: Arnold Moyaux Date: Thu, 3 Feb 2022 14:58:58 +0000 Subject: [PATCH] [FIX] stock_picking_batch: wave immediate transfer Usecase to reproduce: - Create an immediate transfer and enable detailed opeations on the picking type - Create 2 `stock.move.line` with qty_done = 5 - Add the picking to a new wave and select only one of the sml Traceback It happens because the move split is base on the reserved quantity. However in the case of an immediate transfer, the reserved quantity is zero and the split fail X-original-commit: 709372b0160a93cb9c30d391c4b3fc6c07ea2f9a Part-of: odoo/odoo#85038 --- .../models/stock_move_line.py | 5 +- .../models/stock_picking_batch.py | 4 +- .../tests/test_wave_picking.py | 50 +++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/addons/stock_picking_batch/models/stock_move_line.py b/addons/stock_picking_batch/models/stock_move_line.py index 6454f858017..393e700c75a 100644 --- a/addons/stock_picking_batch/models/stock_move_line.py +++ b/addons/stock_picking_batch/models/stock_move_line.py @@ -67,7 +67,10 @@ class StockMoveLine(models.Model): picking_to_wave_vals['move_ids'] += [Command.link(move.id)] continue # Split the move - qty = sum(move_lines.mapped('reserved_qty')) + if move.from_immediate_transfer: + qty = sum(move_lines.mapped('qty_done')) + else: + qty = sum(move_lines.mapped('reserved_qty')) new_move = move._split(qty) new_move[0]['move_line_ids'] = [Command.set(move_lines.ids)] picking_to_wave_vals['move_ids'] += [Command.create(new_move[0])] diff --git a/addons/stock_picking_batch/models/stock_picking_batch.py b/addons/stock_picking_batch/models/stock_picking_batch.py index 5d56b2aa48f..b114fe41968 100644 --- a/addons/stock_picking_batch/models/stock_picking_batch.py +++ b/addons/stock_picking_batch/models/stock_picking_batch.py @@ -3,6 +3,7 @@ from odoo import api, fields, models, _ from odoo.exceptions import UserError +from odoo.osv.expression import AND from odoo.tools.float_utils import float_compare, float_is_zero, float_round class StockPickingBatch(models.Model): @@ -91,9 +92,10 @@ class StockPickingBatch(models.Model): domain_states.append('draft') domain = [ ('company_id', '=', batch.company_id.id), - ('immediate_transfer', '=', False), ('state', 'in', domain_states), ] + if not batch.is_wave: + domain = AND([domain, [('immediate_transfer', '=', False)]]) if batch.picking_type_id: domain += [('picking_type_id', '=', batch.picking_type_id.id)] batch.allowed_picking_ids = self.env['stock.picking'].search(domain) diff --git a/addons/stock_picking_batch/tests/test_wave_picking.py b/addons/stock_picking_batch/tests/test_wave_picking.py index 86fdee1ff61..8fe874d39a7 100644 --- a/addons/stock_picking_batch/tests/test_wave_picking.py +++ b/addons/stock_picking_batch/tests/test_wave_picking.py @@ -322,6 +322,56 @@ class TestBatchPicking(TransactionCase): self.assertEqual(lines.batch_id, wave) self.assertEqual(dozen_move.product_uom_qty, 0.58) + def test_wave_mutliple_move_lines(self): + self.productA = self.env['product.product'].create({ + 'name': 'Product Test A', + 'type': 'product', + 'categ_id': self.env.ref('product.product_category_all').id, + }) + picking = self.env['stock.picking'].create({ + 'location_id': self.stock_location.id, + 'location_dest_id': self.customer_location.id, + 'picking_type_id': self.picking_type_out, + 'company_id': self.env.company.id, + 'immediate_transfer': True, + }) + ml1 = self.env['stock.move.line'].create({ + 'product_id': self.productA.id, + 'qty_done': 5, + 'product_uom_id': self.productA.uom_id.id, + 'picking_id': picking.id, + 'location_id': self.stock_location.id, + 'location_dest_id': self.customer_location.id, + }) + self.env['stock.move.line'].create({ + 'product_id': self.productA.id, + 'qty_done': 5, + 'product_uom_id': self.productA.uom_id.id, + 'picking_id': picking.id, + 'location_id': self.stock_location.id, + 'location_dest_id': self.customer_location.id, + }) + + ml2 = self.env['stock.move.line'].create({ + 'product_id': self.productA.id, + 'qty_done': 5, + 'product_uom_id': self.productA.uom_id.id, + 'picking_id': picking.id, + 'location_id': self.stock_location.id, + 'location_dest_id': self.customer_location.id, + }) + picking.action_confirm() + + ml1._add_to_wave() + wave = self.env['stock.picking.batch'].search([ + ('is_wave', '=', True) + ]) + self.assertFalse(picking.batch_id) + self.assertEqual(ml1.picking_id.batch_id.id, wave.id) + self.assertEqual(ml1.picking_id.move_ids.product_uom_qty, 5) + self.assertEqual(ml2.picking_id.id, picking.id) + self.assertEqual(ml2.picking_id.move_ids.product_uom_qty, 10) + def test_wave_trigger_errors(self): with self.assertRaises(UserError): lines = self.picking_client_1.move_line_ids