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 1 commit
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
10 changes: 9 additions & 1 deletion stock_warehouse_flow/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@
# 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 _action_confirm(self, merge=True, merge_into=False):
# Apply the flow configuration on the move before it generates
# its chained moves (if any)
Expand Down
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
25 changes: 25 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
Loading