From 0c150e2713906126b5dfb24490ca434b57f2d9ae Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Wed, 29 Mar 2023 17:03:06 +0200 Subject: [PATCH 1/5] [IMP] stock_picking_volume: Avoid useless recompute Makes computed fields readonly in state 'done' or 'cancel' to avoid triggering recompute when these values are useless --- stock_picking_volume/models/stock_move.py | 6 +++++- stock_picking_volume/models/stock_picking.py | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/stock_picking_volume/models/stock_move.py b/stock_picking_volume/models/stock_move.py index 846dbe4f3..74d7335f0 100644 --- a/stock_picking_volume/models/stock_move.py +++ b/stock_picking_volume/models/stock_move.py @@ -10,7 +10,11 @@ class StockMove(models.Model): _inherit = "stock.move" volume = fields.Float( - compute="_compute_volume", readonly=False, store=True, compute_sudo=True + compute="_compute_volume", + readonly=False, + store=True, + compute_sudo=True, + states={"done": [("readonly", True)], "cancel": [("readonly", True)]}, ) volume_uom_name = fields.Char( diff --git a/stock_picking_volume/models/stock_picking.py b/stock_picking_volume/models/stock_picking.py index b426d7977..5b3f88d19 100644 --- a/stock_picking_volume/models/stock_picking.py +++ b/stock_picking_volume/models/stock_picking.py @@ -10,7 +10,11 @@ class StockPicking(models.Model): _inherit = "stock.picking" volume = fields.Float( - compute="_compute_volume", readonly=False, store=True, compute_sudo=True + compute="_compute_volume", + readonly=False, + store=True, + compute_sudo=True, + states={"done": [("readonly", True)], "cancel": [("readonly", True)]}, ) volume_uom_name = fields.Char( string="Volume unit of measure label", compute="_compute_volume_uom_name" From dc8c5a478a7b4bd2f19721453ed69504cc8192a0 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Wed, 29 Mar 2023 17:04:45 +0200 Subject: [PATCH 2/5] [IMP] stock_picking_volume: Speedup installation Init computed fields from plain sql queries to speedup install on large database --- stock_picking_volume/__init__.py | 2 +- stock_picking_volume/__manifest__.py | 1 - stock_picking_volume/hooks.py | 67 +++++++++++++++++++++------- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/stock_picking_volume/__init__.py b/stock_picking_volume/__init__.py index f69c7729c..6d58305f5 100644 --- a/stock_picking_volume/__init__.py +++ b/stock_picking_volume/__init__.py @@ -1,2 +1,2 @@ from . import models -from .hooks import post_init_hook, pre_init_hook +from .hooks import pre_init_hook diff --git a/stock_picking_volume/__manifest__.py b/stock_picking_volume/__manifest__.py index 493c2a6a0..1de5ffe3c 100644 --- a/stock_picking_volume/__manifest__.py +++ b/stock_picking_volume/__manifest__.py @@ -20,7 +20,6 @@ "views/stock_move.xml", ], "demo": [], - "post_init_hook": "post_init_hook", "pre_init_hook": "pre_init_hook", "development_status": "Beta", } diff --git a/stock_picking_volume/hooks.py b/stock_picking_volume/hooks.py index 6ed58d7cd..2fb34ef29 100644 --- a/stock_picking_volume/hooks.py +++ b/stock_picking_volume/hooks.py @@ -3,30 +3,65 @@ import logging -from odoo import SUPERUSER_ID, api from odoo.tools.sql import column_exists, create_column _logger = logging.getLogger(__name__) -def post_init_hook(cr, registry): - """Post init hook to set compute the volume on pending move and pickings.""" - env = api.Environment(cr, SUPERUSER_ID, {}) - pickings = env["stock.picking"].search([("state", "not in", ["done", "cancel"])]) - moves = env["stock.move"].search( - [ - "|", - ("state", "not in", ["done", "cancel"]), - ("picking_id", "in", pickings.ids), - ] - ) - _logger.info("Compute volumes for %d moves", len(moves)) - moves._compute_volume() - - def pre_init_hook(cr): """Pre init create volume column on stock.picking and stock.move""" if not column_exists(cr, "stock_move", "volume"): create_column(cr, "stock_move", "volume", "numeric") + # First we compute the reserved qty by move_id + # the reserved qty is the sum of the reserved qty of the move lines + # linked to the move + # Then we update the volume of the moves not in state done or cancel + # If the move is in state partially available, or assigned, the volume + # is the reserved qty * the product volume + # else the volume is the move quantity * the product volume + cr.execute( + """ + with reserved_qty_by_move as ( + select + move_id, + product_id, + sum(product_qty) as product_qty + from stock_move_line + group by move_id, product_id + ) + update stock_move + set volume = + CASE + WHEN state in ('partially_available', 'assigned') THEN + product_qty * pp.volume + ELSE + product_uom_qty * pp.volume + END + from reserved_qty_by_move + join product_product pp on pp.id = product_id + where + stock_move.id = reserved_qty_by_move.move_id + and state not in ('done', 'cancel') + """ + ) + _logger.info(f"{cr.rowcount} rows updated in stock_move") + if not column_exists(cr, "stock_picking", "volume"): create_column(cr, "stock_picking", "volume", "numeric") + # we recompute the volume of the pickings not in state done or cancel + # the volume is the sum of the volume of the moves linked to the picking + # that are not in state done or cancel + cr.execute( + """ + update stock_picking + set volume = ( + select sum(volume) + from stock_move + where + stock_move.picking_id = stock_picking.id + and state not in ('done', 'cancel') + ) + where state not in ('done', 'cancel') + """ + ) + _logger.info(f"{cr.rowcount} rows updated in stock_picking") From f0ad221f1a50ec1c796dad196a9eb421c706c3dc Mon Sep 17 00:00:00 2001 From: ferran-S73 Date: Wed, 28 Feb 2024 12:26:09 +0100 Subject: [PATCH 3/5] [FIX] stock_pikcing_volume: ambiguous column --- stock_picking_volume/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock_picking_volume/hooks.py b/stock_picking_volume/hooks.py index 2fb34ef29..f3fc65dee 100644 --- a/stock_picking_volume/hooks.py +++ b/stock_picking_volume/hooks.py @@ -38,7 +38,7 @@ def pre_init_hook(cr): product_uom_qty * pp.volume END from reserved_qty_by_move - join product_product pp on pp.id = product_id + join product_product pp on pp.id = reserved_qty_by_move.product_id where stock_move.id = reserved_qty_by_move.move_id and state not in ('done', 'cancel') From 7815b1c8dc0e867a741d8c392a1ee266131b6104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Wed, 28 Aug 2024 15:00:06 +0200 Subject: [PATCH 4/5] stock_picking_volume: pre_init_hook, replace column type from 'numeric' to 'double precision' As no digits parameters are provided on `.volume' and '.volume' fields, the 'double precision' type is used instead of 'numeric'. This avoids time consuming SQL requests 'ALTER TABLE...' at module install. --- stock_picking_volume/hooks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock_picking_volume/hooks.py b/stock_picking_volume/hooks.py index f3fc65dee..6323ee692 100644 --- a/stock_picking_volume/hooks.py +++ b/stock_picking_volume/hooks.py @@ -11,7 +11,7 @@ _logger = logging.getLogger(__name__) def pre_init_hook(cr): """Pre init create volume column on stock.picking and stock.move""" if not column_exists(cr, "stock_move", "volume"): - create_column(cr, "stock_move", "volume", "numeric") + create_column(cr, "stock_move", "volume", "double precision") # First we compute the reserved qty by move_id # the reserved qty is the sum of the reserved qty of the move lines # linked to the move @@ -47,7 +47,7 @@ def pre_init_hook(cr): _logger.info(f"{cr.rowcount} rows updated in stock_move") if not column_exists(cr, "stock_picking", "volume"): - create_column(cr, "stock_picking", "volume", "numeric") + create_column(cr, "stock_picking", "volume", "double precision") # we recompute the volume of the pickings not in state done or cancel # the volume is the sum of the volume of the moves linked to the picking # that are not in state done or cancel From 5fa689a2da2b777ad167300b37c38e19b9fd09f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Alix?= Date: Wed, 28 Aug 2024 15:32:08 +0200 Subject: [PATCH 5/5] [FIX] stock_pikcing_volume: pre_init_hook, ambiguous columns --- stock_picking_volume/hooks.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stock_picking_volume/hooks.py b/stock_picking_volume/hooks.py index 6323ee692..7ec2217de 100644 --- a/stock_picking_volume/hooks.py +++ b/stock_picking_volume/hooks.py @@ -32,16 +32,16 @@ def pre_init_hook(cr): update stock_move set volume = CASE - WHEN state in ('partially_available', 'assigned') THEN - product_qty * pp.volume + WHEN stock_move.state in ('partially_available', 'assigned') THEN + reserved_qty_by_move.product_qty * pp.volume ELSE - product_uom_qty * pp.volume + stock_move.product_uom_qty * pp.volume END from reserved_qty_by_move join product_product pp on pp.id = reserved_qty_by_move.product_id where stock_move.id = reserved_qty_by_move.move_id - and state not in ('done', 'cancel') + and stock_move.state not in ('done', 'cancel') """ ) _logger.info(f"{cr.rowcount} rows updated in stock_move")