Skip to content

Commit

Permalink
[IMP] stock: pre-compute quantity_done
Browse files Browse the repository at this point in the history
The field stock.move.quantity_done has passed to be stored.

In large databases (millions of records) it takes a good amount of time
to compute it by the ORM, so it's worth it to pre-compute its values as
much as possible.

TT46020
  • Loading branch information
chienandalu committed Nov 8, 2024
1 parent d4a4264 commit dabc812
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
17 changes: 17 additions & 0 deletions openupgrade_scripts/scripts/stock/16.0.1.1/post-migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,25 @@ def _handle_stock_picking_backorder_strategy(env):
)


def _complete_stock_move_quantity_done_with_orm(env):
"""In pre-migration we left out the moves with lines with different units of
measure to be treated by the ORM"""
env.cr.execute(
"""
SELECT move_id
FROM stock_move_line
GROUP BY move_id
HAVING COUNT(DISTINCT product_uom_id) > 1
AND SUM(qty_done) <> 0
"""
)
move_ids = [id for id, *_ in env.cr.fetchall() if id]
env["stock.move"].browse(move_ids)._quantity_done_compute()


@openupgrade.migrate()
def migrate(env, version):
_handle_multi_location_visibility(env)
_handle_stock_picking_backorder_strategy(env)
openupgrade.load_data(env.cr, "stock", "16.0.1.1/noupdate_changes.xml")
_complete_stock_move_quantity_done_with_orm(env)
54 changes: 54 additions & 0 deletions openupgrade_scripts/scripts/stock/16.0.1.1/pre-migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,59 @@ def _handle_stock_picking_backorder_strategy(env):
)


def _prefill_stock_move_quantity_done(env):
"""It's going to be an stored field now. Let's try to speed up the field
computation so it performs better in larga stock_move tables"""
if not openupgrade.column_exists(env.cr, "stock_move", "quantity_done"):
openupgrade.add_fields(
env,
[
(
"quantity_done",
"stock.move",
"stock_move",
"float",
False,
"stock",
)
],
)
# For moves with lines with different units of measure we rather pass them through
# the ORM in post-migration, although this will deal with the vast majority of
# moves.
openupgrade.logged_query(
env.cr,
"""
WITH precision_cte AS (
SELECT digits FROM decimal_precision
WHERE name = 'Product Unit of Measure' LIMIT 1
),
consistent_moves AS (
SELECT move_id
FROM stock_move_line
GROUP BY move_id
HAVING COUNT(DISTINCT product_uom_id) = 1 AND SUM(qty_done) <> 0
),
move_quantities AS (
SELECT sm.id AS move_id,
-- Round the values to the current decimal precision in case it changed
-- in the past
SUM(
ROUND(sml.qty_done, (SELECT digits FROM precision_cte))
) AS total_quantity_done
FROM stock_move sm
JOIN stock_move_line sml ON sm.id = sml.move_id
WHERE sm.id IN (SELECT move_id FROM consistent_moves)
GROUP BY sm.id
)
UPDATE stock_move
SET quantity_done = mq.total_quantity_done
FROM move_quantities mq
WHERE stock_move.id = mq.move_id;
""",
)


@openupgrade.migrate()
def migrate(env, version):
openupgrade.rename_tables(env.cr, _tables_renames)
Expand All @@ -138,3 +191,4 @@ def migrate(env, version):
_update_sol_product_category_name(env)
_compute_stock_location_replenish_location(env)
_handle_stock_picking_backorder_strategy(env)
_prefill_stock_move_quantity_done(env)
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ stock / stock.move / lot_ids (many2many) : relati
# NOTHING TO DO

stock / stock.move / quantity_done (float) : is now stored
# NOTHING TO DO: handle by ORM, can improve in the future
# DONE: pre-migration: pre-compute the majority for performance post-migration: compute with ORM the rest

stock / stock.move / route_ids (many2many) : relation is now 'stock.route' ('stock.location.route') [nothing to do]
# NOTHING TO DO
Expand Down

0 comments on commit dabc812

Please sign in to comment.