mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[FIX] stock_vertical_lift: handles multiple move lines on pick
If there is two move lines for the same product in the vertical lift (stored in2 differents trays for instance), the pick scenario was failing when the user was processing the first line. To circumvent this, instead of validating directly the move, we put the line in its own stock move, then we put the stock move in its own transfer and validate this one. Methods used to do that have been copied from the `shopfloor` module, they probably deserves their own module as they are quite generic.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
{
|
||||
"name": "Vertical Lift",
|
||||
"summary": "Provides the core for integration with Vertical Lifts",
|
||||
"version": "13.0.1.1.1",
|
||||
"version": "13.0.1.1.2",
|
||||
"category": "Stock",
|
||||
"author": "Camptocamp, Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
|
||||
@@ -7,7 +7,27 @@
|
||||
<field name="product_id" ref="product_running_socks" />
|
||||
<field name="product_uom_id" ref="uom.product_uom_unit" />
|
||||
<field name="inventory_id" ref="stock_inventory_vertical_lift_0" />
|
||||
<field name="product_qty">30.0</field>
|
||||
<field name="product_qty">10.0</field>
|
||||
<field
|
||||
name="location_id"
|
||||
ref="stock_location_vertical_lift_demo_tray_1b_x1y2"
|
||||
/>
|
||||
</record>
|
||||
<record id="stock_inventory_vertical_lift_line_2" model="stock.inventory.line">
|
||||
<field name="product_id" ref="product_running_socks" />
|
||||
<field name="product_uom_id" ref="uom.product_uom_unit" />
|
||||
<field name="inventory_id" ref="stock_inventory_vertical_lift_0" />
|
||||
<field name="product_qty">10.0</field>
|
||||
<field
|
||||
name="location_id"
|
||||
ref="stock_location_vertical_lift_demo_tray_1b_x2y2"
|
||||
/>
|
||||
</record>
|
||||
<record id="stock_inventory_vertical_lift_line_3" model="stock.inventory.line">
|
||||
<field name="product_id" ref="product_running_socks" />
|
||||
<field name="product_uom_id" ref="uom.product_uom_unit" />
|
||||
<field name="inventory_id" ref="stock_inventory_vertical_lift_0" />
|
||||
<field name="product_qty">10.0</field>
|
||||
<field
|
||||
name="location_id"
|
||||
ref="stock_location_vertical_lift_demo_tray_1b_x3y2"
|
||||
|
||||
@@ -125,6 +125,14 @@ msgstr ""
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_vertical_lift
|
||||
#: code:addons/stock_vertical_lift/models/vertical_lift_operation_base.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Created from backorder <a href=# data-oe-model=stock.picking data-oe-"
|
||||
"id=%d>%s</a>."
|
||||
msgstr ""
|
||||
|
||||
#. module: stock_vertical_lift
|
||||
#: model:ir.model.fields,field_description:stock_vertical_lift.field_vertical_lift_command__create_date
|
||||
#: model:ir.model.fields,field_description:stock_vertical_lift.field_vertical_lift_operation_inventory__create_date
|
||||
|
||||
@@ -11,6 +11,79 @@ from odoo.addons.base_sparse_field.models.fields import Serialized
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# The following methods have been copied from 'shopfloor' module (OCA/wms)
|
||||
# TODO: we should move them in a generic module
|
||||
|
||||
|
||||
def split_other_move_lines(move, move_lines):
|
||||
"""Substract `move_lines` from `move.move_line_ids`, put the result
|
||||
in a new move and returns it.
|
||||
"""
|
||||
other_move_lines = move.move_line_ids - move_lines
|
||||
if other_move_lines or move.state == "partially_available":
|
||||
qty_to_split = move.product_uom_qty - sum(move_lines.mapped("product_uom_qty"))
|
||||
backorder_move_id = move._split(qty_to_split)
|
||||
backorder_move = move.browse(backorder_move_id)
|
||||
backorder_move.move_line_ids = other_move_lines
|
||||
backorder_move._recompute_state()
|
||||
backorder_move._action_assign()
|
||||
move._recompute_state()
|
||||
return backorder_move
|
||||
return False
|
||||
|
||||
|
||||
def extract_and_action_done(move):
|
||||
"""Extract the moves in a separate transfer and validate them.
|
||||
|
||||
You can combine this method with `split_other_move_lines` method
|
||||
to first extract some move lines in a separate move, then validate it
|
||||
with this method.
|
||||
"""
|
||||
# Put remaining qty to process from partially available moves
|
||||
# in their own move (which will be then 'confirmed')
|
||||
partial_moves = move.filtered(lambda m: m.state == "partially_available")
|
||||
for partial_move in partial_moves:
|
||||
partial_move.split_other_move_lines(partial_move.move_line_ids)
|
||||
# Process assigned moves
|
||||
moves = move.filtered(lambda m: m.state == "assigned")
|
||||
if not moves:
|
||||
return False
|
||||
for picking in moves.picking_id:
|
||||
moves_todo = picking.move_lines & moves
|
||||
if moves_todo == picking.move_lines:
|
||||
# No need to create a new transfer if we are processing all moves
|
||||
new_picking = picking
|
||||
else:
|
||||
new_picking = picking.copy(
|
||||
{
|
||||
"name": "/",
|
||||
"move_lines": [],
|
||||
"move_line_ids": [],
|
||||
"backorder_id": picking.id,
|
||||
}
|
||||
)
|
||||
new_picking.message_post(
|
||||
body=_(
|
||||
"Created from backorder "
|
||||
"<a href=# data-oe-model=stock.picking data-oe-id=%d>%s</a>."
|
||||
)
|
||||
% (picking.id, picking.name)
|
||||
)
|
||||
moves_todo.write({"picking_id": new_picking.id})
|
||||
moves_todo.package_level_id.write({"picking_id": new_picking.id})
|
||||
moves_todo.move_line_ids.write({"picking_id": new_picking.id})
|
||||
moves_todo.move_line_ids.package_level_id.write(
|
||||
{"picking_id": new_picking.id}
|
||||
)
|
||||
new_picking.action_assign()
|
||||
assert new_picking.state == "assigned"
|
||||
new_picking.action_done()
|
||||
return True
|
||||
|
||||
|
||||
# /methods
|
||||
|
||||
|
||||
class VerticalLiftOperationBase(models.AbstractModel):
|
||||
"""Base model for shuttle operations (pick, put, inventory)"""
|
||||
|
||||
@@ -412,7 +485,9 @@ class VerticalLiftOperationTransfer(models.AbstractModel):
|
||||
line = self.current_move_line_id
|
||||
if line.state in ("assigned", "partially_available"):
|
||||
line.qty_done = line.product_qty
|
||||
line.move_id._action_done()
|
||||
# if the move has other move lines, it is split to have only this move line
|
||||
split_other_move_lines(line.move_id, line)
|
||||
extract_and_action_done(line.move_id)
|
||||
return True
|
||||
|
||||
def fetch_tray(self):
|
||||
|
||||
@@ -154,10 +154,11 @@ class VerticalLiftCase(common.LocationTrayTypeCase):
|
||||
inventory.action_start()
|
||||
return inventory
|
||||
|
||||
def _test_button_release(self, move_line, expected_state):
|
||||
# for the test, we'll consider our last line has been delivered
|
||||
move_line.qty_done = move_line.product_qty
|
||||
move_line.move_id._action_done()
|
||||
def _test_button_release(self, move_lines, expected_state):
|
||||
# for the test, we'll consider all the lines has been delivered
|
||||
for move_line in move_lines:
|
||||
move_line.qty_done = move_line.product_qty
|
||||
move_lines.picking_id.action_done()
|
||||
# release, no further operation in queue
|
||||
operation = self.shuttle._operation_for_mode()
|
||||
# the release button can be used only in the state... release
|
||||
|
||||
@@ -13,7 +13,7 @@ class TestPick(VerticalLiftCase):
|
||||
)
|
||||
# we have a move line to pick created by demo picking
|
||||
# stock_picking_out_demo_vertical_lift_1
|
||||
cls.out_move_line = cls.picking_out.move_line_ids
|
||||
cls.out_move_line = cls.picking_out.move_line_ids[0]
|
||||
|
||||
def test_switch_pick(self):
|
||||
self.shuttle.switch_pick()
|
||||
@@ -159,7 +159,7 @@ class TestPick(VerticalLiftCase):
|
||||
|
||||
def test_button_release(self):
|
||||
self._open_screen("pick")
|
||||
self._test_button_release(self.out_move_line, "noop")
|
||||
self._test_button_release(self.picking_out.move_line_ids, "noop")
|
||||
|
||||
def test_process_current_pick(self):
|
||||
operation = self._open_screen("pick")
|
||||
@@ -183,7 +183,7 @@ class TestPick(VerticalLiftCase):
|
||||
# fmt: off
|
||||
'cells': [
|
||||
[0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 1, 0, 0, 0, 0, 0],
|
||||
[1, 1, 1, 0, 0, 0, 0, 0],
|
||||
]
|
||||
# fmt: on
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user