From bcad62e049d41b451662ffdac65265bcaeca70e0 Mon Sep 17 00:00:00 2001 From: William Henrotin Date: Fri, 16 Jun 2023 11:49:03 +0200 Subject: [PATCH] [IMP] stock: remove compute move without packages The move without package as computed field bring some issue with the "no save detailed operation" feature. Creating a stock move and directly add some move lines without saving do not call `set_move_ids_without_package` Task: 3256447 Part-of: odoo/odoo#124409 --- addons/stock/models/stock_move_line.py | 1 + addons/stock/models/stock_picking.py | 42 ++++++---------------- addons/stock/tests/test_packing.py | 4 +-- addons/stock/views/stock_picking_views.xml | 1 + 4 files changed, 14 insertions(+), 34 deletions(-) diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py index 5d110db65e7..12c33ab26f1 100644 --- a/addons/stock/models/stock_move_line.py +++ b/addons/stock/models/stock_move_line.py @@ -895,6 +895,7 @@ class StockMoveLine(models.Model): 'restrict_partner_id': self.picking_id.owner_id.id, 'company_id': self.picking_id.company_id.id, 'partner_id': self.picking_id.partner_id.id, + 'package_level_id': self.package_level_id.id, } def _copy_quant_info(self, vals): diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 5bdcce3e28d..66bd9073f08 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -405,9 +405,8 @@ class Picking(models.Model): compute="_compute_location_id", store=True, precompute=True, readonly=False, check_company=True, required=True) move_ids = fields.One2many('stock.move', 'picking_id', string="Stock Moves", copy=True) - move_ids_without_package = fields.Many2many( - 'stock.move', string="Stock moves not in package", compute='_compute_move_without_package', - inverse='_set_move_without_package', compute_sudo=True) + move_ids_without_package = fields.One2many( + 'stock.move', 'picking_id', string="Stock moves not in package", domain=['|', ('package_level_id', '=', False), ('picking_type_entire_packs', '=', False)]) has_scrap_move = fields.Boolean( 'Has Scrap Moves', compute='_has_scrap_move') picking_type_id = fields.Many2one( @@ -971,35 +970,6 @@ class Picking(models.Model): subtype_id=subtype_id, ) - @api.depends('state', 'move_ids', 'move_ids.state', 'move_ids.package_level_id', 'move_ids.move_line_ids.package_level_id') - def _compute_move_without_package(self): - for picking in self: - picking.move_ids_without_package = picking._get_move_ids_without_package() - - def _set_move_without_package(self): - new_mwp = self[0].move_ids_without_package - for picking in self: - old_mwp = picking._get_move_ids_without_package() - picking.move_ids = (picking.move_ids - old_mwp) | new_mwp - moves_to_unlink = old_mwp - new_mwp - if moves_to_unlink: - moves_to_unlink.unlink() - - def _get_move_ids_without_package(self): - self.ensure_one() - move_ids_without_package = self.env['stock.move'] - if not self.picking_type_entire_packs: - move_ids_without_package = self.move_ids - else: - for move in self.move_ids: - if not move.package_level_id: - if move.state == 'assigned' and move.picking_id or move.state == 'done': - if any(not ml.package_level_id for ml in move.move_line_ids): - move_ids_without_package |= move - else: - move_ids_without_package |= move - return move_ids_without_package.filtered(lambda move: not move.scrap_id) - def _check_move_lines_map_quant_package(self, package): return package._check_move_lines_map_quant(self.move_line_ids.filtered(lambda ml: ml.package_id == package), 'reserved_qty') @@ -1048,6 +1018,10 @@ class Picking(models.Model): }) for pl in package_level_ids: pl.location_dest_id = self._get_entire_pack_location_dest(pl.move_line_ids) or picking.location_dest_id.id + for move in move_lines_to_pack.move_id: + if all(line.package_level_id for line in move.move_line_ids) \ + and len(move.move_line_ids.package_level_id) == 1: + move.package_level_id = move.move_line_ids.package_level_id def _get_lot_move_lines_for_sanity_check(self, none_done_picking_ids, separate_pickings=True): """ Get all move_lines with tracked products that need to be checked over in the sanity check. @@ -1569,6 +1543,10 @@ class Picking(models.Model): def action_put_in_pack(self): self.ensure_one() if self.state not in ('done', 'cancel'): + if self.immediate_transfer: + for move in self.move_ids: + if float_is_zero(move.quantity_done, precision_rounding=move.product_uom.rounding): + move.quantity_done = move.product_qty picking_move_lines = self.move_line_ids if ( not self.picking_type_id.show_reserved diff --git a/addons/stock/tests/test_packing.py b/addons/stock/tests/test_packing.py index 83a8e86cc41..f4ffe607059 100644 --- a/addons/stock/tests/test_packing.py +++ b/addons/stock/tests/test_packing.py @@ -85,10 +85,10 @@ class TestPacking(TestPackingCommon): pick_picking.move_line_ids.filtered(lambda ml: ml.product_id == self.productA and ml.qty_done == 0.0).qty_done = 4.0 pick_picking.move_line_ids.filtered(lambda ml: ml.product_id == self.productB and ml.qty_done == 0.0).qty_done = 3.0 second_pack = pick_picking.action_put_in_pack() - self.assertEqual(len(pick_picking.move_ids_without_package), 0) + self.assertEqual(len(pick_picking.move_ids_without_package), 2) self.assertEqual(len(packing_picking.move_ids_without_package), 2) pick_picking.button_validate() - self.assertEqual(len(packing_picking.move_ids_without_package), 0) + self.assertEqual(len(packing_picking.move_ids_without_package), 2) self.assertEqual(len(first_pack.quant_ids), 2) self.assertEqual(len(second_pack.quant_ids), 2) packing_picking.action_assign() diff --git a/addons/stock/views/stock_picking_views.xml b/addons/stock/views/stock_picking_views.xml index 297700fe609..dd151a20e7c 100644 --- a/addons/stock/views/stock_picking_views.xml +++ b/addons/stock/views/stock_picking_views.xml @@ -301,6 +301,7 @@ +