Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion stock_warehouse_flow/README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

====================
Stock Warehouse Flow
====================
Expand All @@ -13,7 +17,7 @@ Stock Warehouse Flow
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github
Expand Down
2 changes: 1 addition & 1 deletion stock_warehouse_flow/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"author": "Camptocamp, BCIM, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/wms",
"category": "Warehouse Management",
"version": "16.0.1.1.0",
"version": "16.0.1.2.0",
"license": "AGPL-3",
"depends": [
# core
Expand Down
26 changes: 24 additions & 2 deletions stock_warehouse_flow/i18n/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,14 @@ msgstr "Mostrar Nombre"
#: model:ir.model.fields,help:stock_warehouse_flow.field_stock_warehouse_flow__move_domain
msgid ""
"Domain based on Stock Moves, to define if the routing flow is applicable or "
"not."
"not.\n"
"Use 'wh_total_products' to set flow routes based on the quantity assigned to "
"each warehouse."
msgstr ""
"Dominio basado en Movimientos de existencias, para definir si el flujo de "
"enrutamiento es aplicable o no."
"enrutamiento es aplicable o no.\n"
"Usa 'wh_total_products' para establecer los flujos de ruta en función de la "
"cantidad asignada a cada almacén."

#. module: stock_warehouse_flow
#. odoo-python
Expand Down Expand Up @@ -438,6 +442,24 @@ msgstr "Almacén"
msgid "Warehouse Flow"
msgstr "Flujo de Almacén"

#. module: stock_warehouse_flow
#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_move__wh_total_products
msgid "Wh Total Products"
msgstr "Total productos por almacén"

#. module: stock_warehouse_flow
#: model:ir.model.fields,help:stock_warehouse_flow.field_stock_move__wh_total_products
msgid ""
"Total product units for the same sale order and warehouse. Equivalent to "
"sale.order.total_products but scoped to the warehouse assigned to this "
"move, useful for flow domain evaluation in multi-warehouse (omnichannel) "
"scenarios."
msgstr ""
"Total de unidades de producto para el mismo pedido de venta y almacén. "
"Equivalente a sale.order.total_products pero limitado al almacén asignado "
"a este movimiento, útil para la evaluación de dominios de flujo en "
"escenarios multi-almacén."

#. module: stock_warehouse_flow
#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_warehouse_flow__warning
msgid "Warning"
Expand Down
18 changes: 17 additions & 1 deletion stock_warehouse_flow/i18n/stock_warehouse_flow.pot
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ msgstr ""
#: model:ir.model.fields,help:stock_warehouse_flow.field_stock_warehouse_flow__move_domain
msgid ""
"Domain based on Stock Moves, to define if the routing flow is applicable or "
"not."
"not.\n"
"Use 'wh_total_products' to set flow routes based on the quantity assigned to "
"each warehouse."
msgstr ""

#. module: stock_warehouse_flow
Expand Down Expand Up @@ -416,6 +418,20 @@ msgstr ""
msgid "Warehouse Flow"
msgstr ""

#. module: stock_warehouse_flow
#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_move__wh_total_products
msgid "Wh Total Products"
msgstr ""

#. module: stock_warehouse_flow
#: model:ir.model.fields,help:stock_warehouse_flow.field_stock_move__wh_total_products
msgid ""
"Total product units for the same sale order and warehouse. Equivalent to "
"sale.order.total_products but scoped to the warehouse assigned to this "
"move, useful for flow domain evaluation in multi-warehouse (omnichannel) "
"scenarios."
msgstr ""

#. module: stock_warehouse_flow
#: model:ir.model.fields,field_description:stock_warehouse_flow.field_stock_warehouse_flow__warning
msgid "Warning"
Expand Down
54 changes: 53 additions & 1 deletion stock_warehouse_flow/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Copyright 2022 Camptocamp SA
# Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
# © 2026 FactorLibre - Adriana Saiz <adriana.saiz@factorlibre.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import fields, models
from odoo import api, fields, models


class StockMove(models.Model):
Expand All @@ -15,6 +16,57 @@ class StockMove(models.Model):
"before a new flow is applied."
),
)
wh_total_products = fields.Float(
compute="_compute_wh_total_products",
help=(
"Total product units for the same sale order and warehouse. "
"Equivalent to sale.order.total_products but scoped to the "
"warehouse assigned to this move, useful for flow domain "
"evaluation in multi-warehouse (omnichannel) scenarios."
),
)

@api.depends(
"sale_line_id.order_id",
"warehouse_id",
"picking_type_id.warehouse_id",
"product_uom_qty",
)
def _compute_wh_total_products(self):
"""Sum product_uom_qty of outgoing sibling moves sharing same SO and warehouse.

Groups all non-cancelled outgoing moves by (sale_order, warehouse) in a
single query, then assigns each group's total. Moves without
sale_line_id fall back to their own product_uom_qty.

Only outgoing moves are counted to avoid inflating the total with
incoming (return) moves from exchange claims.

Uses picking_type_id.warehouse_id as fallback when warehouse_id
is not set (common after flow application in multi-warehouse scenarios).
"""
moves_with_sale = self.filtered("sale_line_id")
for move in self - moves_with_sale:
move.wh_total_products = move.product_uom_qty
if not moves_with_sale:
return
order_ids = moves_with_sale.sale_line_id.order_id.ids
all_siblings = self.search(
[
("sale_line_id.order_id", "in", order_ids),
("state", "!=", "cancel"),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should state be present on api.depends?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Sergio, the state we filter on (!= cancel) belongs to sibling moves fetched via search(), not to the record itself.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

understood, thanks!

("picking_type_id.code", "=", "outgoing"),
]
)
totals = {}
for sibling in all_siblings:
wh = sibling.warehouse_id or sibling.picking_type_id.warehouse_id
key = (sibling.sale_line_id.order_id.id, wh.id)
totals[key] = totals.get(key, 0.0) + sibling.product_uom_qty
for move in moves_with_sale:
wh = move.warehouse_id or move.picking_type_id.warehouse_id
key = (move.sale_line_id.order_id.id, wh.id)
move.wh_total_products = totals.get(key, move.product_uom_qty)

def _apply_flow_on_action_confirm(self):
if self.rule_id.route_id.apply_flow_on != "on_confirm":
Expand Down
4 changes: 3 additions & 1 deletion stock_warehouse_flow/models/stock_warehouse_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class StockWarehouseFlow(models.Model):
default=[],
copy=False,
help="Domain based on Stock Moves, to define if the "
"routing flow is applicable or not.",
"routing flow is applicable or not.\n"
"Use 'wh_total_products' to set flow routes based on "
"the quantity assigned to each warehouse.",
)
delivery_steps = fields.Selection(
selection=[
Expand Down
1 change: 1 addition & 0 deletions stock_warehouse_flow/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from . import test_delivery_carrier
from . import test_warehouse
from . import test_warehouse_flow
from . import test_wh_total_products
Loading
Loading