-
-
Notifications
You must be signed in to change notification settings - Fork 195
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
[13.0] Add Dynamic Routing #31
Conversation
Detailed commit history for the past developments can be found in https://github.com/guewen/stock-logistics-warehouse/tree/12.0-add-stock_picking_zone
* if the move's dest location is a child of the routing's dest location: it's more precise so change only the picking type * if the move's dest location is a parent of the routing's dest location: change the dest location to the routing's dest location and change the picking type * if the move's dest location is outside of the routing's dest location: add a routing operation before It means, when there is a routing, even if the location was already correct, the picking type is changed so users handle transfers the same way. The same changes will be done on the destination routing
We can probably optimize it by appling the domain only once for all the moves of a routing. The same thing should be applied on destination routing.
when we have to apply a routing instead of using unreserve: any side-effect will be cancelled before doing the routing and calling assign again, thus we avoid leaving things behind.
The relation from the move doesn't always exist, if we delete the package level before the unreserve, they are properly deleted.
Rules can be ordered and excluded by domains. Store the rule chosen for a move to avoid doing it twice.
A split must occur to handle the routing only on the available quantity.
When a move source location changes or a new move is inserted in the chain, reevaluate the routing rules so we can chain several rules.
The _split method expects product_qty, not product_uom_qty. So get the missing reserved quantity and convert it in the unit of product_qty (as done in StockMove._action_assign())
In some conditions, new_moves can contain the same moves as self, so _action_assign() would be called twice on the same move and would have duplicate move lines.
No longer needed after the last refactoring
* Prevent calling _action_assign() twice in case the savepoint was released * Do not apply routing rules on the move we just routed as the routing rule to apply will be the same and already done * Add comments explaining why they are called
In case of a put-away, when using a push routing rule, we want to keep the expected destination. For instance, we have a move: * Input -> Highbay (draft) It's assigned and the put-away rules compute a move line going to Highbay/X1Y2. When a routing is applied, before this commit, it would add a move at the end, it would look like: * Input -> Handover (assigned) * Handover -> Highbay (confirmed) On reservation of the second move (Handover -> Highbay), it would compute again the put away rules to find a place in the whole highbay. With the change now, the moves would look like: * Input -> Handover (assigned) * Handover -> Highbay/X1Y2 (confirmed) So the move line cannot go elsewhere. To implement this, I decided to remove the 'routing_rule_id' field stored on 'stock.move', as this field is only needed by the methods _apply_routing_rule_pull/push and never afterwards. The original location has to be propagated to these methods as well, so now there is a single dict of values used to apply the rules.
When an ormcache is cleared, it propagates the invalidation to other workers, blowing all their caches for all models. Since we use this cache only for the duration of a method, it's pointless.
By using the parent path of the records, we can avoid many SQL requests to compare children or find parent locations
The picking type must be selected to filter on routing to apply
There is no real reason to force using the exact same location. A sub-location should be fine.
On stock.move, the `package_level_id` field did not have a `copy=False` attribute when version 13.0 of Odoo was released. So when we create a new move, the package level of the move being copied was linked as well to the new move. It has been fixed recently in odoo in odoo/odoo@ecf726a but to be on the safe side if the code is not up-to-date, it's anyway better to force a False value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧠 on 🔥 😅
# by the method. | ||
move.with_context(exclude_apply_dynamic_routing=True)._action_assign() | ||
|
||
pickings_to_check_for_emptiness._dynamic_routing_handle_empty() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, the routed moves are assigned 3 times.
The first, which is rollbacked, to know if yes or no a routing needs to be applied.
A second, right after the routing is applied, to ensure the reserved products are the same as during the 1st action_assign call.
And finally a third in the original _action_assign
call.
To avoid this 3rd one, we could here return the routed moves.
Then in _split_and_apply_routing
we could return something like moves - routed_moves
.
Then, only the moves, which already had their routing applied will be returned to _action_assign'. So at the end,
_action_assign` will have been called :
once for moves with no routing rules.
twice (one roll backed) on moves that already had been routed before
twice on the moves that just had been routed. (instead of 3 times).
What do you think?
Else it seems all good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method _action_assign
ignores moves with a state assigned
and we know the routed moves have this state (they would not be routed if not assigned, and they can't be partially available because they are split to be available).
This PR has the |
@guewen would you like to squash some commits? |
/ocabot merge nobump |
On my way to merge this fine PR! |
Congratulations, your PR was merged at 7353e97. Thanks a lot for contributing to OCA. ❤️ |
…rontend Location content transfer frontend
Moved from OCA/stock-logistics-warehouse#788
Description
Standard Stock Routes explain the steps you want to produce whereas the
“Dynamic Routing” defines how operations are grouped according to their final
source and destination location.
This allows for example:
them in two different operation type
the sub-location waves
Context for the use cases:
In the warehouse, you have a High-Bay which requires to place goods in a
handover when you move goods in or out of it. The High-Bay contains many
sub-locations.
A product can be stored either in the High-Bay, either in the Shelving zone.
When picking:
When there is enough stock in the Shelving, you expect the moves to have the
usual Pick(Highbay)-Pack-Ship steps. If the good is picked from the High-Bay, you will
need an extra operation: Pick(Highbay)-Handover-Pack-Ship.
This is what this feature is doing: on the High-Bay location, you define
a "routing rule". A routing rule selects a different operation type for the move.
The extra transfer will have the selected operation type, and be added
dynamically, on reservation, before the chain of moves.
When putting away:
A put-away rule targets the High-Bay location.
An operation Input-Highbay is created. You expect Input-Handover-Highbay.
You can configure a dynamic routing for the put-away on the High-Bay Location.
The operation type of the new Handover move will the one of the matching routing rule,
and its destination will be the destination of the operation type.
Try on runbot
In Inventory Settings, activate:
The initial setup in the demo data contains locations:
The "Highbay" location (and children) is configured to:
goods are taken from Highbay (using a new picking type Highbay → Handover)
goods are put to Highbay (using a new picking type Handover → Highbay)
Steps to try the Pull Routing Transfer:
Steps to try the Push Routing Transfer:
In the "WH/Stock" location, create a Put-Away Strategy with:
Create a new purchase order of:
Confirm the purchase
You'll have 2 transfers: