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..7ec2217de 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") + 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 + # 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 stock_move.state in ('partially_available', 'assigned') THEN + reserved_qty_by_move.product_qty * pp.volume + ELSE + 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 stock_move.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") + 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 + 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") 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"