diff --git a/stock_vertical_lift/models/__init__.py b/stock_vertical_lift/models/__init__.py
index 839f04888..87a31d40b 100644
--- a/stock_vertical_lift/models/__init__.py
+++ b/stock_vertical_lift/models/__init__.py
@@ -3,6 +3,7 @@ from . import vertical_lift_operation_base
from . import vertical_lift_operation_pick
from . import vertical_lift_operation_put
from . import vertical_lift_operation_inventory
+from . import stock_inventory
from . import stock_location
from . import stock_move
from . import stock_move_line
diff --git a/stock_vertical_lift/models/stock_inventory.py b/stock_vertical_lift/models/stock_inventory.py
new file mode 100644
index 000000000..8e87e556e
--- /dev/null
+++ b/stock_vertical_lift/models/stock_inventory.py
@@ -0,0 +1,27 @@
+# Copyright 2019 Camptocamp SA
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+
+
+class InventoryLine(models.Model):
+ _inherit = "stock.inventory.line"
+
+ vertical_lift_done = fields.Boolean(default=False)
+ # Field used to sort lines by tray on the inventory scan screen, so entire
+ # trays are processed one after the other
+ vertical_lift_tray_id = fields.Many2one(
+ comodel_name="stock.location",
+ compute="_compute_vertical_lift_tray_id",
+ readonly=True,
+ store=True,
+ )
+
+ @api.depends("location_id.vertical_lift_kind")
+ def _compute_vertical_lift_tray_id(self):
+ for line in self:
+ if line.location_id.vertical_lift_kind == "cell":
+ # The parent of the cell is the tray.
+ line.vertical_lift_tray_id = line.location_id.location_id
+ else:
+ line.vertical_lift_tray_id = False
diff --git a/stock_vertical_lift/models/vertical_lift_operation_base.py b/stock_vertical_lift/models/vertical_lift_operation_base.py
index 8d0656cbc..5c1d09e75 100644
--- a/stock_vertical_lift/models/vertical_lift_operation_base.py
+++ b/stock_vertical_lift/models/vertical_lift_operation_base.py
@@ -19,6 +19,13 @@ class VerticalLiftOperationBase(models.AbstractModel):
location_id = fields.Many2one(
related="shuttle_id.location_id", readonly=True
)
+ number_of_ops = fields.Integer(
+ compute="_compute_number_of_ops", string="Number of Operations"
+ )
+ number_of_ops_all = fields.Integer(
+ compute="_compute_number_of_ops_all",
+ string="Number of Operations in all shuttles",
+ )
mode = fields.Selection(related="shuttle_id.mode", readonly=True)
operation_descr = fields.Char(
string="Operation", default="...", readonly=True
@@ -32,6 +39,16 @@ class VerticalLiftOperationBase(models.AbstractModel):
)
]
+ @api.depends()
+ def _compute_number_of_ops(self):
+ for record in self:
+ record.number_of_ops = 0
+
+ @api.depends()
+ def _compute_number_of_ops_all(self):
+ for record in self:
+ record.number_of_ops_all = 0
+
def on_barcode_scanned(self, barcode):
self.ensure_one()
# to implement in sub-classes
@@ -51,6 +68,35 @@ class VerticalLiftOperationBase(models.AbstractModel):
def action_manual_barcode(self):
return self.shuttle_id.action_manual_barcode()
+ def button_save(self):
+ """Process the action (pick, put, ...)"""
+ raise NotImplementedError
+
+ def button_release(self):
+ """Release the operation, go to the next"""
+ raise NotImplementedError
+
+ def _render_product_packagings(self, product):
+ values = {
+ "packagings": [
+ {"name": pkg.name, "qty": pkg.qty, "unit": product.uom_id.name}
+ for pkg in product.packaging_ids
+ ]
+ }
+ content = self.env["ir.qweb"].render(
+ "stock_vertical_lift.packagings", values
+ )
+ return content
+
+ def _get_tray_qty(self, product, location):
+ quants = self.env["stock.quant"].search(
+ [
+ ("location_id", "=", location.id),
+ ("product_id", "=", product.id),
+ ]
+ )
+ return sum(quants.mapped("quantity"))
+
class VerticalLiftOperationTransfer(models.AbstractModel):
"""Base model for shuttle pick and put operations"""
@@ -63,14 +109,6 @@ class VerticalLiftOperationTransfer(models.AbstractModel):
comodel_name="stock.move.line", readonly=True
)
- number_of_ops = fields.Integer(
- compute="_compute_number_of_ops", string="Number of Operations"
- )
- number_of_ops_all = fields.Integer(
- compute="_compute_number_of_ops_all",
- string="Number of Operations in all shuttles",
- )
-
tray_location_id = fields.Many2one(
comodel_name="stock.location",
compute="_compute_tray_data",
@@ -137,21 +175,10 @@ class VerticalLiftOperationTransfer(models.AbstractModel):
def _compute_product_packagings(self):
for record in self:
if not record.current_move_line_id:
+ record.product_packagings = ""
continue
product = record.current_move_line_id.product_id
- values = {
- "packagings": [
- {
- "name": pkg.name,
- "qty": pkg.qty,
- "unit": product.uom_id.name,
- }
- for pkg in product.packaging_ids
- ]
- }
- content = self.env["ir.qweb"].render(
- "stock_vertical_lift.packagings", values
- )
+ content = self._render_product_packagings(product)
record.product_packagings = content
@api.depends()
@@ -168,17 +195,12 @@ class VerticalLiftOperationTransfer(models.AbstractModel):
def _compute_tray_qty(self):
for record in self:
if not (record.tray_location_id and record.current_move_line_id):
+ record.tray_qty = 0.
continue
product = record.current_move_line_id.product_id
- quants = self.env["stock.quant"].search(
- [
- ("location_id", "=", record.tray_location_id.id),
- ("product_id", "=", product.id),
- ]
- )
- record.tray_qty = sum(quants.mapped("quantity"))
+ location = record.tray_location_id
+ record.tray_qty = self._get_tray_qty(product, location)
- # depends of the quantity so we can't have all triggers
@api.depends("current_move_line_id")
def _compute_tray_data(self):
for record in self:
@@ -245,4 +267,4 @@ class VerticalLiftOperationTransfer(models.AbstractModel):
self.operation_descr = _("Release")
def fetch_tray(self):
- return
+ raise NotImplementedError
diff --git a/stock_vertical_lift/models/vertical_lift_operation_inventory.py b/stock_vertical_lift/models/vertical_lift_operation_inventory.py
index 17fd732cd..d1a6088ed 100644
--- a/stock_vertical_lift/models/vertical_lift_operation_inventory.py
+++ b/stock_vertical_lift/models/vertical_lift_operation_inventory.py
@@ -1,10 +1,261 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from odoo import models
+from odoo import _, api, fields, models
+from odoo.addons.base_sparse_field.models.fields import Serialized
+from odoo.tools import float_compare
+
+# TODO handle autofocus + easy way to validate for the input field
class VerticalLiftOperationInventory(models.Model):
- _name = 'vertical.lift.operation.inventory'
- _inherit = 'vertical.lift.operation.base'
- _description = 'Vertical Lift Operation Inventory'
+ _name = "vertical.lift.operation.inventory"
+ _inherit = "vertical.lift.operation.base"
+ _description = "Vertical Lift Operation Inventory"
+
+ current_inventory_line_id = fields.Many2one(
+ comodel_name="stock.inventory.line", readonly=True
+ )
+
+ quantity_input = fields.Float()
+ # if the quantity is wrong, user has to write 2 times
+ # the same quantity to really confirm it's correct
+ last_quantity_input = fields.Float()
+ state = fields.Selection(
+ selection=[
+ ("quantity", "Inventory, please enter the amount"),
+ (
+ "confirm_wrong_quantity",
+ "The quantity does not match, are you sure?",
+ ),
+ ("save", "Save"),
+ ],
+ default="quantity",
+ )
+
+ tray_location_id = fields.Many2one(
+ comodel_name="stock.location",
+ compute="_compute_tray_data",
+ string="Tray Location",
+ )
+ tray_name = fields.Char(compute="_compute_tray_data", string="Tray Name")
+ tray_type_id = fields.Many2one(
+ comodel_name="stock.location.tray.type",
+ compute="_compute_tray_data",
+ string="Tray Type",
+ )
+ tray_type_code = fields.Char(
+ compute="_compute_tray_data", string="Tray Code"
+ )
+ tray_x = fields.Integer(string="X", compute="_compute_tray_data")
+ tray_y = fields.Integer(string="Y", compute="_compute_tray_data")
+ tray_matrix = Serialized(string="Cells", compute="_compute_tray_data")
+ tray_qty = fields.Float(
+ string="Stock Quantity", compute="_compute_tray_qty"
+ )
+
+ # current operation information
+ inventory_id = fields.Many2one(
+ related="current_inventory_line_id.inventory_id", readonly=True
+ )
+ product_id = fields.Many2one(
+ related="current_inventory_line_id.product_id", readonly=True
+ )
+ product_uom_id = fields.Many2one(
+ related="current_inventory_line_id.product_uom_id", readonly=True
+ )
+ product_qty = fields.Float(
+ related="current_inventory_line_id.product_qty", readonly=True
+ )
+ product_packagings = fields.Html(
+ string="Packaging", compute="_compute_product_packagings"
+ )
+ package_id = fields.Many2one(
+ related="current_inventory_line_id.package_id", readonly=True
+ )
+ lot_id = fields.Many2one(
+ related="current_inventory_line_id.prod_lot_id", readonly=True
+ )
+
+ @api.depends("current_inventory_line_id")
+ def _compute_tray_data(self):
+ for record in self:
+ location = record.current_inventory_line_id.location_id
+ tray_type = location.location_id.tray_type_id
+ # this is the current cell
+ record.tray_location_id = location.id
+ # name of the tray where the cell is
+ record.tray_name = location.location_id.name
+ record.tray_type_id = tray_type.id
+ record.tray_type_code = tray_type.code
+ record.tray_x = location.posx
+ record.tray_y = location.posy
+ record.tray_matrix = location.tray_matrix
+
+ @api.depends("current_inventory_line_id.product_id.packaging_ids")
+ def _compute_product_packagings(self):
+ for record in self:
+ if not record.current_inventory_line_id:
+ record.product_packagings = ""
+ continue
+ product = record.current_inventory_line_id.product_id
+ content = self._render_product_packagings(product)
+ record.product_packagings = content
+
+ @api.depends("tray_location_id", "current_inventory_line_id.product_id")
+ def _compute_tray_qty(self):
+ for record in self:
+ if not (
+ record.tray_location_id and record.current_inventory_line_id
+ ):
+ record.tray_qty = 0.
+ continue
+ product = record.current_inventory_line_id.product_id
+ location = record.tray_location_id
+ record.tray_qty = self._get_tray_qty(product, location)
+
+ def _compute_number_of_ops(self):
+ for record in self:
+ line_model = self.env["stock.inventory.line"]
+ record.number_of_ops = line_model.search_count(
+ self._domain_inventory_lines_to_do()
+ )
+
+ def _compute_number_of_ops_all(self):
+ for record in self:
+ line_model = self.env["stock.inventory.line"]
+ record.number_of_ops_all = line_model.search_count(
+ self._domain_inventory_lines_to_do_all()
+ )
+
+ def _domain_inventory_lines_to_do(self):
+ return [
+ ("location_id", "child_of", self.location_id.id),
+ ("state", "=", "confirm"),
+ ("vertical_lift_done", "=", False),
+ ]
+
+ def _domain_inventory_lines_to_do_all(self):
+ shuttle_locations = self.env["stock.location"].search(
+ [("vertical_lift_kind", "=", "view")]
+ )
+ return [
+ ("location_id", "child_of", shuttle_locations.ids),
+ ("state", "=", "confirm"),
+ ("vertical_lift_done", "=", False),
+ ]
+
+ def on_screen_open(self):
+ """Called when the screen is open"""
+ self.select_next_inventory_line()
+
+ def reset(self):
+ self.write(
+ {
+ "quantity_input": 0.,
+ "last_quantity_input": 0.,
+ "state": "quantity",
+ }
+ )
+ self.update_step_description()
+
+ def step(self):
+ return self.state
+
+ def step_to(self, state):
+ self.state = state
+ self.update_step_description()
+
+ def step_description(self):
+ state_field = self._fields["state"]
+ return state_field.convert_to_export(self.state, self)
+
+ def update_step_description(self):
+ if self.current_inventory_line_id:
+ descr = self.step_description()
+ else:
+ descr = _("No operations")
+ self.operation_descr = descr
+
+ def button_save(self):
+ if not self.current_inventory_line_id:
+ return
+ self.ensure_one()
+ self.process_current()
+ if self.step() == "save":
+ self.select_next_inventory_line()
+ if not self.current_inventory_line_id:
+ # sorry not sorry
+ return {
+ "effect": {
+ "fadeout": "slow",
+ "message": _("Congrats, you cleared the queue!"),
+ "img_url": "/web/static/src/img/smile.svg",
+ "type": "rainbow_man",
+ }
+ }
+
+ def button_release(self):
+ raise NotImplementedError
+
+ def _has_identical_quantity(self):
+ line = self.current_inventory_line_id
+ return (
+ float_compare(
+ line.theoretical_qty,
+ self.quantity_input,
+ precision_rounding=line.product_uom_id.rounding,
+ )
+ == 0
+ )
+
+ def _process_quantity(self):
+ if self.step() == "quantity":
+ if self._has_identical_quantity():
+ self.step_to("save")
+ return True
+ else:
+ self.last_quantity_input = self.quantity_input
+ self.quantity_input = 0.
+ self.step_to("confirm_wrong_quantity")
+ return False
+ if self.step() == "confirm_wrong_quantity":
+ if self.quantity_input == self.last_quantity_input:
+ # confirms the previous input
+ self.step_to("save")
+ return True
+ else:
+ # cycle back to the first quantity check
+ self.step_to("quantity")
+ return self._process_quantity()
+
+ def process_current(self):
+ line = self.current_inventory_line_id
+ if self._process_quantity() and not line.vertical_lift_done:
+ line.vertical_lift_done = True
+ if self.quantity_input != line.product_qty:
+ line.product_qty = self.quantity_input
+ inventory = line.inventory_id
+ if all(line.vertical_lift_done for line in inventory.line_ids):
+ inventory.action_validate()
+
+ def fetch_tray(self):
+ location = self.current_inventory_line_id.location_id
+ location.fetch_vertical_lift_tray()
+
+ def select_next_inventory_line(self):
+ self.ensure_one()
+ next_line = self.env["stock.inventory.line"].search(
+ self._domain_inventory_lines_to_do(),
+ limit=1,
+ order="vertical_lift_tray_id, location_id, id",
+ )
+ previous_line = self.current_inventory_line_id
+ self.current_inventory_line_id = next_line
+ self.reset()
+ if (
+ next_line
+ and previous_line.vertical_lift_tray_id
+ != next_line.vertical_lift_tray_id
+ ):
+ self.fetch_tray()
diff --git a/stock_vertical_lift/readme/ROADMAP.rst b/stock_vertical_lift/readme/ROADMAP.rst
index c56a03077..84079ec4c 100644
--- a/stock_vertical_lift/readme/ROADMAP.rst
+++ b/stock_vertical_lift/readme/ROADMAP.rst
@@ -1,3 +1,8 @@
-* Complete Pick screen and workflow (currently enough for a demo, not for production)
-* Implement Put-away screen and workflow
-* Implement Inventory screen and workflow
+* Complete screen workflows (currently enough for a demo, not for production)
+* Inventory: find a way to have a nice autofocus for quantity, still compatible
+ with barcode scanner (Odoo disables the autofocus when using barcode, which
+ makes sense)
+* Put-away: handle packages
+* Handle "multi-shuttle" put-away
+* Create glue module for product_expiry
+* Challenge the save + release buttons and workflow
diff --git a/stock_vertical_lift/tests/common.py b/stock_vertical_lift/tests/common.py
index f40456ffc..0a6b613bc 100644
--- a/stock_vertical_lift/tests/common.py
+++ b/stock_vertical_lift/tests/common.py
@@ -21,6 +21,47 @@ class VerticalLiftCase(common.LocationTrayTypeCase):
cls.vertical_lift_loc = cls.env.ref(
'stock_vertical_lift.stock_location_vertical_lift'
)
+ cls.location_1a = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_1a"
+ )
+ cls.location_1a_x1y1 = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_1a_x1y1"
+ )
+ cls.location_1a_x2y1 = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_1a_x2y1"
+ )
+ cls.location_1a_x3y1 = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_1a_x3y1"
+ )
+ cls.location_1a_x1y2 = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_1a_x1y2"
+ )
+ cls.location_1b_x1y1 = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_1b_x1y1"
+ )
+ cls.location_1b_x1y2 = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_1b_x1y2"
+ )
+ cls.location_2a = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_2a"
+ )
+ cls.location_2a_x1y1 = cls.env.ref(
+ "stock_vertical_lift."
+ "stock_location_vertical_lift_demo_tray_2a_x1y1"
+ )
+
+ def _update_qty_in_location(self, location, product, quantity):
+ self.env["stock.quant"]._update_available_quantity(
+ product, location, quantity
+ )
@classmethod
def _create_simple_picking_out(cls, product, quantity):
@@ -81,6 +122,25 @@ class VerticalLiftCase(common.LocationTrayTypeCase):
}
)
+ @classmethod
+ def _create_inventory(self, products):
+ """Create a draft inventory
+
+ Products is a list of tuples (bin location, product).
+ """
+ values = {
+ 'name': 'Test Inventory',
+ 'filter': 'partial',
+ 'line_ids': [(0, 0, {
+ 'product_id': product.id,
+ 'product_uom_id': product.uom_id.id,
+ 'location_id': location.id
+ }) for location, product in products]
+ }
+ inventory = self.env['stock.inventory'].create(values)
+ inventory.action_start()
+ return inventory
+
def _test_button_release(self, move_line):
# for the test, we'll consider our last line has been delivered
move_line.qty_done = move_line.product_qty
diff --git a/stock_vertical_lift/tests/test_inventory.py b/stock_vertical_lift/tests/test_inventory.py
index 864c022ba..68caaf609 100644
--- a/stock_vertical_lift/tests/test_inventory.py
+++ b/stock_vertical_lift/tests/test_inventory.py
@@ -1,31 +1,110 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-import unittest
-
+from odoo import _
from .common import VerticalLiftCase
class TestInventory(VerticalLiftCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.picking_out = cls.env.ref(
- "stock_vertical_lift.stock_picking_out_demo_vertical_lift_1"
- )
- # 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
-
def test_switch_inventory(self):
self.shuttle.switch_inventory()
self.assertEqual(self.shuttle.mode, "inventory")
+ self.assertEqual(
+ self.shuttle._operation_for_mode().current_inventory_line_id,
+ self.env["stock.inventory.line"].browse(),
+ )
- @unittest.skip("Not implemented")
- def test_inventory_count_move_lines(self):
- pass
-
- @unittest.skip("Not implemented")
- def test_process_current_inventory(self):
- # test to implement when the code is implemented
+ def test_inventory_action_open_screen(self):
self.shuttle.switch_inventory()
+ action = self.shuttle.action_open_screen()
+ operation = self.shuttle._operation_for_mode()
+ self.assertEqual(action["type"], "ir.actions.act_window")
+ self.assertEqual(
+ action["res_model"], "vertical.lift.operation.inventory"
+ )
+ self.assertEqual(action["res_id"], operation.id)
+
+ def test_inventory_count_ops(self):
+ self._update_qty_in_location(
+ self.location_1a_x1y1, self.product_socks, 10
+ )
+ self._update_qty_in_location(
+ self.location_1a_x2y1, self.product_recovery, 10
+ )
+ self._create_inventory(
+ [
+ (self.location_1a_x1y1, self.product_socks),
+ (self.location_1a_x2y1, self.product_recovery),
+ ]
+ )
+ self._update_qty_in_location(
+ self.location_2a_x1y1, self.product_socks, 10
+ )
+ self._create_inventory([(self.location_2a_x1y1, self.product_socks)])
+
+ self.shuttle.switch_inventory()
+ operation = self.shuttle._operation_for_mode()
+ self.assertEqual(operation.number_of_ops, 2)
+ self.assertEqual(operation.number_of_ops_all, 3)
+
+ def test_process_current_inventory(self):
+ self._update_qty_in_location(
+ self.location_1a_x1y1, self.product_socks, 10
+ )
+ inventory = self._create_inventory(
+ [(self.location_1a_x1y1, self.product_socks)]
+ )
+ self.shuttle.switch_inventory()
+ operation = self.shuttle._operation_for_mode()
+ self.assertEqual(
+ operation.current_inventory_line_id, inventory.line_ids
+ )
+ # test the happy path, quantity is correct
+ operation.quantity_input = 10.0
+ result = operation.button_save()
+ # state is reset
+ self.assertEqual(operation.state, "quantity")
+ self.assertFalse(operation.current_inventory_line_id)
+ self.assertEqual(operation.operation_descr, _("No operations"))
+ self.assertTrue(inventory.line_ids.vertical_lift_done)
+ self.assertEqual(inventory.state, "done")
+ expected_result = {
+ "effect": {
+ "fadeout": "slow",
+ "message": _("Congrats, you cleared the queue!"),
+ "img_url": "/web/static/src/img/smile.svg",
+ "type": "rainbow_man",
+ }
+ }
+ self.assertEqual(result, expected_result)
+
+ def test_wrong_quantity(self):
+ self._update_qty_in_location(
+ self.location_1a_x1y1, self.product_socks, 10
+ )
+ inventory = self._create_inventory(
+ [(self.location_1a_x1y1, self.product_socks)]
+ )
+ self.shuttle.switch_inventory()
+ operation = self.shuttle._operation_for_mode()
+ line = operation.current_inventory_line_id
+ self.assertEqual(line, inventory.line_ids)
+
+ operation.quantity_input = 12.0
+ operation.button_save()
+ self.assertEqual(operation.last_quantity_input, 12.0)
+ self.assertEqual(operation.quantity_input, 0.0)
+ self.assertEqual(operation.state, "confirm_wrong_quantity")
+ self.assertEqual(operation.current_inventory_line_id, line)
+ self.assertEqual(
+ operation.operation_descr,
+ _("The quantity does not match, are you sure?"),
+ )
+
+ # entering the same quantity a second time validates
+ operation.quantity_input = 12.0
+ operation.button_save()
+ self.assertFalse(operation.current_inventory_line_id)
+
+ self.assertTrue(inventory.line_ids.vertical_lift_done)
+ self.assertEqual(inventory.state, "done")
diff --git a/stock_vertical_lift/tests/test_put.py b/stock_vertical_lift/tests/test_put.py
index f13038906..d3f391100 100644
--- a/stock_vertical_lift/tests/test_put.py
+++ b/stock_vertical_lift/tests/test_put.py
@@ -13,22 +13,6 @@ class TestPut(VerticalLiftCase):
)
cls.picking_in.action_confirm()
cls.in_move_line = cls.picking_in.move_line_ids
- cls.location_1a_x1y1 = cls.env.ref(
- "stock_vertical_lift."
- "stock_location_vertical_lift_demo_tray_1a_x1y1"
- )
- cls.location_1a_x2y1 = cls.env.ref(
- "stock_vertical_lift."
- "stock_location_vertical_lift_demo_tray_1a_x2y1"
- )
- cls.location_1a_x3y1 = cls.env.ref(
- "stock_vertical_lift."
- "stock_location_vertical_lift_demo_tray_1a_x3y1"
- )
- cls.location_1a_x1y2 = cls.env.ref(
- "stock_vertical_lift."
- "stock_location_vertical_lift_demo_tray_1a_x1y2"
- )
cls.in_move_line.location_dest_id = cls.location_1a_x3y1
def _select_move_lines(self, shuttle, move_lines=None):
@@ -107,10 +91,6 @@ class TestPut(VerticalLiftCase):
def test_put_count_move_lines(self):
self.shuttle.switch_put()
self.picking_in.action_cancel()
- location_2a_x1y1 = self.env.ref(
- "stock_vertical_lift."
- "stock_location_vertical_lift_demo_tray_2a_x1y1"
- )
put1 = self._create_simple_picking_in(
self.product_socks, 10, self.location_1a_x1y1
)
@@ -120,7 +100,7 @@ class TestPut(VerticalLiftCase):
)
put2.action_confirm()
put3 = self._create_simple_picking_in(
- self.product_recovery, 10, location_2a_x1y1
+ self.product_recovery, 10, self.location_2a_x1y1
)
put3.action_confirm()
operation = self.shuttle._operation_for_mode()
diff --git a/stock_vertical_lift/views/vertical_lift_operation_base_views.xml b/stock_vertical_lift/views/vertical_lift_operation_base_views.xml
index 60457ce93..fa665be90 100644
--- a/stock_vertical_lift/views/vertical_lift_operation_base_views.xml
+++ b/stock_vertical_lift/views/vertical_lift_operation_base_views.xml
@@ -37,6 +37,9 @@