From 1a1c59095d80e6648b5a2fb2f1c93d4e9583d106 Mon Sep 17 00:00:00 2001 From: William Henrotin Date: Wed, 3 Apr 2024 12:40:27 +0000 Subject: [PATCH] [FIX] mrp_subcontracting_dropshipping: don't assign twice The `stock.move:_action_done()` already reserve the next mto moves at validation. Calling the reservation method after the validation again may lead to unwanted results like calling `check_entire_pack()` and messed up the result_package_id on the stock move lines. Task : 3764822 closes odoo/odoo#161445 X-original-commit: 2551f735e24eb2549264b0a70b814be8d3c52922 Signed-off-by: Arnold Moyaux (arm) Signed-off-by: William Henrotin (whe) --- .../models/stock_picking.py | 1 - addons/stock/models/stock_picking.py | 14 ++--- addons/stock/tests/test_packing.py | 57 +++++++++++++++++++ 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/addons/mrp_subcontracting_dropshipping/models/stock_picking.py b/addons/mrp_subcontracting_dropshipping/models/stock_picking.py index 82ec1c0d8e4..04b889c49a2 100644 --- a/addons/mrp_subcontracting_dropshipping/models/stock_picking.py +++ b/addons/mrp_subcontracting_dropshipping/models/stock_picking.py @@ -20,7 +20,6 @@ class StockPicking(models.Model): def _action_done(self): res = super()._action_done() - self.move_ids.move_dest_ids._action_assign() # If needed, create a compensation layer, so we add the MO cost to the dropship one svls = self.env['stock.valuation.layer'] diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 9f3d2dec17a..ad3095ff09c 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -1028,15 +1028,13 @@ class Picking(models.Model): else: move_lines_in_package_level = move_lines_to_pack.filtered(lambda ml: ml.move_id.package_level_id) move_lines_without_package_level = move_lines_to_pack - move_lines_in_package_level + if package.package_use == 'disposable': + (move_lines_in_package_level | move_lines_without_package_level).result_package_id = package + move_lines_in_package_level.result_package_id = package for ml in move_lines_in_package_level: - ml.write({ - 'result_package_id': package.id, - 'package_level_id': ml.move_id.package_level_id.id, - }) - move_lines_without_package_level.write({ - 'result_package_id': package.id, - 'package_level_id': package_level_ids[0].id, - }) + ml.package_level_id = ml.move_id.package_level_id.id + move_lines_without_package_level.package_level_id = package_level_ids[0].id + for pl in package_level_ids: pl.location_dest_id = pickings._get_entire_pack_location_dest(pl.move_line_ids) or pickings.location_dest_id.id for move in move_lines_to_pack.move_id: diff --git a/addons/stock/tests/test_packing.py b/addons/stock/tests/test_packing.py index a323cd701db..ee1cde2ecb4 100644 --- a/addons/stock/tests/test_packing.py +++ b/addons/stock/tests/test_packing.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import odoo.tests from odoo.tests import Form from odoo.tests.common import TransactionCase from odoo.tools import float_round @@ -1702,3 +1703,59 @@ class TestPacking(TestPackingCommon): (picking1 | picking2).with_context(default_picking_type_id=self.ref('stock.picking_type_out'))._compute_hide_picking_type() self.assertTrue(picking1.hide_picking_type) self.assertFalse(picking2.hide_picking_type) + + +@odoo.tests.tagged('post_install', '-at_install') +class TestPackagePropagation(TestPackingCommon): + + def test_reusable_package_propagation(self): + """ Test a reusable package should not be propagated to the next picking + of a mto chain """ + reusable_package = self.env['stock.quant.package'].create({ + 'name': 'Reusable Package', + 'package_use': 'reusable', + }) + disposable_package = self.env['stock.quant.package'].create({ + 'name': 'disposable Package', + 'package_use': 'disposable', + }) + self.productA = self.env['product.product'].create({ + 'name': 'productA', + 'type': 'product', + 'tracking': 'none', + }) + self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 2) + pg = self.env['procurement.group'].create({'name': 'propagation_test'}) + self.env['procurement.group'].run([ + pg.Procurement( + self.productA, + 2.0, + self.productA.uom_id, + self.customer_location, + 'propagation_test', + 'propagation_test', + self.warehouse.company_id, + { + 'warehouse_id': self.warehouse, + 'group_id': pg + } + ) + ]) + picking = self.env['stock.picking'].search([ + ('group_id', '=', pg.id), + ('location_id', '=', self.stock_location.id), + ]) + picking.action_assign() + picking.move_ids.move_line_ids.result_package_id = reusable_package + picking.move_ids.move_line_ids.copy({'result_package_id': disposable_package.id}) + picking.move_ids.move_line_ids.quantity = 1 + picking.button_validate() + self.assertEqual(picking.state, 'done') + pack_lines = self.env['stock.picking'].search([ + ('group_id', '=', pg.id), + ('location_id', '=', self.pack_location.id), + ]).move_line_ids + + self.assertEqual(len(pack_lines), 2, 'Should have only 2 stock move line') + self.assertFalse(pack_lines[0].result_package_id, 'Should not have the reusable package') + self.assertEqual(pack_lines[1].result_package_id, disposable_package, 'Should have only the disposable package')