Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0][IMP] stock_warehouse_flow: Improve flow matching #991

Open
wants to merge 5 commits into
base: 14.0
Choose a base branch
from
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: 6 additions & 0 deletions setup/stock_warehouse_flow_delivery_refresh/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
2 changes: 1 addition & 1 deletion stock_warehouse_flow/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Stock Warehouse Flow
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f7e133c4dd3a58cee27199b4d9d633379d3f3819d75b4b3b9e32e3145abc1099
!! source digest: sha256:f7d01f91ec1206e84284b1b59e764f190751f15d1e9849036adb40c43baade48
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
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": "14.0.2.0.2",
"version": "14.0.2.1.0",
"license": "AGPL-3",
"depends": [
# core
Expand Down
1 change: 1 addition & 0 deletions stock_warehouse_flow/models/stock_location_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class StockLocationRoute(models.Model):
compute="_compute_applicable_flow_ids",
string="Applicable Flows",
)
disable_warehouse_flow_on_confirm = fields.Boolean()

@api.depends("rule_ids.picking_type_id")
def _compute_applicable_flow_ids(self):
Expand Down
18 changes: 14 additions & 4 deletions stock_warehouse_flow/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,25 @@
# Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import models
from odoo import fields, models


class StockMove(models.Model):
_inherit = "stock.move"

default_picking_type_id = fields.Many2one(
"stock.picking.type",
help=(
"Used as a backup to save picking type set by odoo, "
"before a new flow is applied."
),
)

def _apply_flow_on_action_confirm(self):
if self.rule_id.route_id.disable_warehouse_flow_on_confirm:
return False
return self.picking_type_id.code == "outgoing"

def _action_confirm(self, merge=True, merge_into=False):
# Apply the flow configuration on the move before it generates
# its chained moves (if any)
Expand All @@ -26,6 +39,3 @@ def _action_confirm(self, merge=True, merge_into=False):
return super(StockMove, moves_to_confirm)._action_confirm(
merge=merge, merge_into=merge_into
)

def _apply_flow_on_action_confirm(self):
return self.picking_type_id.code == "outgoing"
19 changes: 18 additions & 1 deletion stock_warehouse_flow/models/stock_warehouse_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,17 @@ def action_generate_route(self):

def _search_for_move_domain(self, move):
domain = [
("from_picking_type_id", "=", move.picking_type_id.id),
("delivery_route_id", "!=", False),
]
domain_picking_type = [("from_picking_type_id", "=", move.picking_type_id.id)]
if move.default_picking_type_id:
domain_picking_type = expression.OR(
[
domain_picking_type,
[("from_picking_type_id", "=", move.default_picking_type_id.id)],
]
)
domain = expression.AND([domain, domain_picking_type])
if move.group_id.carrier_id:
domain.append(("carrier_ids", "in", move.group_id.carrier_id.ids))
else:
Expand Down Expand Up @@ -528,7 +536,13 @@ def _apply_on_move(self, move, assign_picking=True):
return False
logger.info("Applying flow '%s' on '%s'", self.name, move)
rule = self._get_rule_from_delivery_route()
# Backup old picking
old_picking = move.picking_id
move.picking_id = False
# Backup default type, as we want to always lookup for rules valid
# for default type, and current type
if not move.default_picking_type_id:
move.default_picking_type_id = move.picking_type_id
move.picking_type_id = self.to_picking_type_id
move.location_id = (
self.to_output_stock_loc_id
Expand All @@ -538,6 +552,9 @@ def _apply_on_move(self, move, assign_picking=True):
move.rule_id = rule
if assign_picking:
move._assign_picking()
# If all moves are moved to another picking, we can unlink the old one.
if not old_picking.move_lines:
old_picking.unlink()

def write(self, vals):
res = super().write(vals)
Expand Down
2 changes: 1 addition & 1 deletion stock_warehouse_flow/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ <h1 class="title">Stock Warehouse Flow</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f7e133c4dd3a58cee27199b4d9d633379d3f3819d75b4b3b9e32e3145abc1099
!! source digest: sha256:f7d01f91ec1206e84284b1b59e764f190751f15d1e9849036adb40c43baade48
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Alpha" src="https://img.shields.io/badge/maturity-Alpha-red.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/wms/tree/14.0/stock_warehouse_flow"><img alt="OCA/wms" src="https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-stock_warehouse_flow"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/wms&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module introduces the concept of routing flows in order to manage
Expand Down
36 changes: 36 additions & 0 deletions stock_warehouse_flow/tests/test_warehouse_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,31 @@


class TestWarehouseFlow(common.CommonFlow):
def test_flow_search_after_applied(self):
flow_ship_only = self._get_flow("ship_only")
flow_pick_ship = self._get_flow("pick_ship")
moves_before = self.env["stock.move"].search([])
self._run_procurement(self.product, 10, flow_pick_ship.carrier_ids)
moves = self.env["stock.move"].search([("id", "not in", moves_before.ids)])
move_ship = moves.filtered(lambda m: m.picking_type_id.code == "outgoing")
# When flow was applied to move, picking type set by odoo was saved
# in default_picking_type_id, and flow.to_picking_type_id is set
self.assertEqual(move_ship.picking_type_id, flow_pick_ship.to_picking_type_id)
default_type = self.env.ref("stock.picking_type_out")
self.assertEqual(move_ship.default_picking_type_id, default_type)
# Only pick_ship matches, because there's a constraint on the carrier
matching_flows = self.env["stock.warehouse.flow"]._search_for_move(move_ship)
self.assertEqual(matching_flows, flow_pick_ship)
# Drop the carrier from the procurement, only direct flow should match
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Drop the carrier from the procurement, only direct flow should match
# Drop the carrier from the procurement, only ship only flow should match

as "direct" is used for shipping policy (confusing)

move_ship.group_id.carrier_id = False
matching_flows = self.env["stock.warehouse.flow"]._search_for_move(move_ship)
self.assertEqual(matching_flows, flow_ship_only)
# Drop default_picking_type_id, no flow is found, because
# now flow has Delivery Orders POST as from_picking_type_id
Comment on lines +30 to +31
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure to understand this comment. Current move operation type (which has been updated at the beginning) doesn't match any flows?

Copy link
Member Author

Choose a reason for hiding this comment

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

You create the move with picking type A.
All flows have from_picking_type_id == A.
If you apply any of those flows to the move, picking_type_id is updated to to_picking_type_id (B).
The only reason why it was matching before is because we made a backup of A in default_picking_type_id.
Drop this backup, it doesn't match any flow anymore.

move_ship.default_picking_type_id = False
matching_flows = self.env["stock.warehouse.flow"]._search_for_move(move_ship)
self.assertFalse(matching_flows)

def test_flow_ship_only(self):
"""Replace the initial move by a 'ship_only' move."""
# NOTE: use the recorder when migrating to 15.0 to catch created moves
Expand Down Expand Up @@ -65,6 +90,17 @@ def test_flow_pick_ship(self):
self.assertEqual(move_ship.state, "assigned")
self._validate_picking(move_ship.picking_id)

def test_disable_flow_at_move_confirm(self):
flow = self._get_flow("pick_ship")
# It is False by default
flow.impacted_route_ids.disable_warehouse_flow_on_confirm = True
moves_before = self.env["stock.move"].search([])
self._run_procurement(self.product, 10, flow.carrier_ids)
moves = self.env["stock.move"].search([("id", "not in", moves_before.ids)])
move_ship = moves.filtered(lambda m: m.picking_type_id.code == "outgoing")
# ensure new move doesn't have flow.to_picking_type_id as picking type
self.assertNotEqual(move_ship.picking_type_id, flow.to_picking_type_id)

def test_no_rule_found_on_delivery_route(self):
flow = self._get_flow("pick_ship")
# Remove the rule
Expand Down
11 changes: 11 additions & 0 deletions stock_warehouse_flow/views/stock_location_route.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,15 @@
</field>
</record>

<record id="stock_location_route_form_view" model="ir.ui.view">
<field name="name">stock.location.route.form.inherit</field>
<field name="model">stock.location.route</field>
<field name="inherit_id" ref="stock.stock_location_route_form_view" />
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="disable_warehouse_flow_on_confirm" />
</field>
</field>
</record>

</odoo>
80 changes: 80 additions & 0 deletions stock_warehouse_flow_delivery_refresh/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
=====================================
Stock Warehouse Flow Delivery Refresh
=====================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8de340e2095dadbecd3245322179db3413e3b25e0da75bd649643ab997eb7a60
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-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
:target: https://github.com/OCA/wms/tree/14.0/stock_warehouse_flow_delivery_refresh
:alt: OCA/wms
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-stock_warehouse_flow_delivery_refresh
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This is a glue module between Stock Warehouse Flow and Stock Available On Premise Release.

This module applies a new Stock Warehouse Flow on Stock Moves when carrier changes on a Stock Picking

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/wms/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/wms/issues/new?body=module:%20stock_warehouse_flow_delivery_refresh%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Camptocamp
* BCIM

Contributors
~~~~~~~~~~~~

* Jacques-Etienne Baudoux <je@bcim.be>
* Matthieu Méquignon <matthieu.mequignon@camptocamp.com>

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/wms <https://github.com/OCA/wms/tree/14.0/stock_warehouse_flow_delivery_refresh>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions stock_warehouse_flow_delivery_refresh/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
14 changes: 14 additions & 0 deletions stock_warehouse_flow_delivery_refresh/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "Stock Warehouse Flow Delivery Refresh",
"summary": "Allow to refresh delivery flow when carrier changes",
"version": "14.0.1.0.0",
"category": "Warehouse Management",
"website": "https://github.com/OCA/wms",
"author": "Camptocamp, BCIM, Odoo Community Association (OCA)",
"license": "AGPL-3",
"installable": True,
"depends": [
"stock_warehouse_flow",
"stock_available_to_promise_release",
],
}
2 changes: 2 additions & 0 deletions stock_warehouse_flow_delivery_refresh/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import stock_move
from . import stock_picking
13 changes: 13 additions & 0 deletions stock_warehouse_flow_delivery_refresh/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025 Camptocamp SA, BCIM
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import api, models

class StockMove(models.Model):
_inherit = "stock.move"

def _stock_warehouse_flow_onchange_carrier(self):
flow_model = self.env["stock.warehouse.flow"]
moves_need_release = self.filtered(lambda m: m.picking_id.need_release)
for move in moves_need_release:
flow_model._search_and_apply_for_move(move, assign_picking=True)
15 changes: 15 additions & 0 deletions stock_warehouse_flow_delivery_refresh/models/stock_picking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2025 Camptocamp SA, BCIM
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import api, models

class StockPicking(models.Model):
_inherit = "stock.picking"

def write(self, values):
picking_carrier_mapping = {p.id: p.carrier_id for p in self}
super().write(values)
pickings_to_update = self.filtered(
lambda p: picking_carrier_mapping.get(p.id) != p.carrier_id
)
pickings_to_update.move_lines._stock_warehouse_flow_onchange_carrier()
2 changes: 2 additions & 0 deletions stock_warehouse_flow_delivery_refresh/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Jacques-Etienne Baudoux <je@bcim.be>
* Matthieu Méquignon <matthieu.mequignon@camptocamp.com>
3 changes: 3 additions & 0 deletions stock_warehouse_flow_delivery_refresh/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This is a glue module between Stock Warehouse Flow and Stock Available On Premise Release.

This module applies a new Stock Warehouse Flow on Stock Moves when carrier changes on a Stock Picking
Loading
Loading