diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py
index 7825dcbf72..351c7d2351 100644
--- a/shopfloor/__manifest__.py
+++ b/shopfloor/__manifest__.py
@@ -6,7 +6,7 @@
{
"name": "Shopfloor",
"summary": "manage warehouse operations with barcode scanners",
- "version": "14.0.4.2.0",
+ "version": "14.0.5.0.0",
"development_status": "Beta",
"category": "Inventory",
"website": "https://github.com/OCA/wms",
diff --git a/shopfloor/data/shopfloor_scenario_data.xml b/shopfloor/data/shopfloor_scenario_data.xml
index 41768a3db3..4ceec12248 100644
--- a/shopfloor/data/shopfloor_scenario_data.xml
+++ b/shopfloor/data/shopfloor_scenario_data.xml
@@ -45,7 +45,8 @@
"no_prefill_qty": true,
"show_oneline_package_content": true,
"auto_post_line": true,
- "scan_location_or_pack_first": true
+ "scan_location_or_pack_first": true,
+ "ask_for_leaf_destination_location" : true
}
diff --git a/shopfloor/migrations/14.0.5.0.0/post-migration.py b/shopfloor/migrations/14.0.5.0.0/post-migration.py
new file mode 100644
index 0000000000..71359aa01b
--- /dev/null
+++ b/shopfloor/migrations/14.0.5.0.0/post-migration.py
@@ -0,0 +1,43 @@
+# Copyright 2023 Camptocamp SA (http://www.camptocamp.com)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+import json
+import logging
+
+from odoo import SUPERUSER_ID, api
+
+_logger = logging.getLogger(__name__)
+
+
+def migrate(cr, version):
+ if not version:
+ return
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ checkout_scenario = env["shopfloor.scenario"].search(
+ [("key", "=", "checkout")]
+ )
+ _update_scenario_options(checkout_scenario)
+ checkout_menus = env["shopfloor.menu"].search(
+ [("scenario_id", "=", checkout_scenario.id)]
+ )
+ _enable_option_in_menus(checkout_menus)
+
+
+def _update_scenario_options(scenario):
+ options = scenario.options
+ options["ask_for_leaf_destination_location"] = True
+ options_edit = json.dumps(options or {}, indent=4, sort_keys=True)
+ scenario.write({"options_edit": options_edit})
+ _logger.info(
+ "Option ask_for_leaf_destination_location added to the Checkout scenario"
+ )
+
+
+def _enable_option_in_menus(menus):
+ for menu in menus:
+ menu.ask_for_leaf_destination_location = True
+ _logger.info(
+ "Option ask_for_leaf_destination_location enabled for menu {}".format(
+ menu.name
+ )
+ )
diff --git a/shopfloor/models/shopfloor_menu.py b/shopfloor/models/shopfloor_menu.py
index 7521a67db4..580090ec6f 100644
--- a/shopfloor/models/shopfloor_menu.py
+++ b/shopfloor/models/shopfloor_menu.py
@@ -53,6 +53,11 @@
to scan a destination package.
"""
+ASK_FOR_LEAF_DESTINATION_LOCATION_HELP = """
+When enabled, the destination location must be a leaf (location with no children)
+location, if it is not, ask for scanning a child location of the destination.
+"""
+
class ShopfloorMenu(models.Model):
_inherit = "shopfloor.menu"
@@ -226,6 +231,14 @@ class ShopfloorMenu(models.Model):
allow_alternative_destination_package_is_possible = fields.Boolean(
compute="_compute_allow_alternative_destination_package_is_possible"
)
+ ask_for_leaf_destination_location = fields.Boolean(
+ string="Ask for leaf destination location",
+ default=False,
+ help=ASK_FOR_LEAF_DESTINATION_LOCATION_HELP,
+ )
+ ask_for_leaf_destination_location_is_possible = fields.Boolean(
+ compute="_compute_ask_for_leaf_destination_location_is_possible"
+ )
@api.onchange("unload_package_at_destination")
def _onchange_unload_package_at_destination(self):
@@ -455,3 +468,10 @@ def _compute_allow_alternative_destination_package_is_possible(self):
menu.allow_alternative_destination_package_is_possible = (
menu.scenario_id.has_option("allow_alternative_destination_package")
)
+
+ @api.depends("scenario_id")
+ def _compute_ask_for_leaf_destination_location_is_possible(self):
+ for menu in self:
+ menu.ask_for_leaf_destination_location_is_possible = (
+ menu.scenario_id.has_option("ask_for_leaf_destination_location")
+ )
diff --git a/shopfloor/services/checkout.py b/shopfloor/services/checkout.py
index e9f9af3385..ce088d0d4b 100644
--- a/shopfloor/services/checkout.py
+++ b/shopfloor/services/checkout.py
@@ -1464,13 +1464,14 @@ def done(self, picking_id, confirmation=False):
)
lines_done = self._lines_checkout_done(picking)
dest_location = picking.location_dest_id
- child_locations = self.env["stock.location"].search(
- [("id", "child_of", dest_location.id), ("usage", "!=", "view")]
- )
- if len(child_locations) > 0 and child_locations != dest_location:
- return self._response_for_select_child_location(
- picking,
+ if self.work.menu.ask_for_leaf_destination_location:
+ child_locations = self.env["stock.location"].search(
+ [("id", "child_of", dest_location.id), ("usage", "!=", "view")]
)
+ if len(child_locations) > 0 and child_locations != dest_location:
+ return self._response_for_select_child_location(
+ picking,
+ )
stock = self._actions_for("stock")
stock.validate_moves(lines_done.move_id)
return self._response_for_select_document(
diff --git a/shopfloor/tests/test_checkout_done.py b/shopfloor/tests/test_checkout_done.py
index a9acce2032..ccd2b173c2 100644
--- a/shopfloor/tests/test_checkout_done.py
+++ b/shopfloor/tests/test_checkout_done.py
@@ -60,11 +60,28 @@ def test_done_partial(self):
)
def test_done_partial_confirm(self):
+ """Check confirm partially done no check for leaf location."""
# lines are done
response = self.service.dispatch(
"done", params={"picking_id": self.picking.id, "confirmation": True}
)
+ self.assertRecordValues(self.picking, [{"state": "done"}])
+
+ self.assert_response(
+ response,
+ next_state="select_document",
+ message=self.service.msg_store.transfer_done_success(self.picking),
+ data={"restrict_scan_first": False},
+ )
+
+ def test_done_partial_confirm_ask_leaf_location(self):
+ """Check confirm partially done with force leaf location option on."""
+ self.menu.sudo().ask_for_leaf_destination_location = True
+ response = self.service.dispatch(
+ "done", params={"picking_id": self.picking.id, "confirmation": True}
+ )
+
self.assertRecordValues(self.picking, [{"state": "assigned"}])
self.assert_response(
diff --git a/shopfloor/views/shopfloor_menu.xml b/shopfloor/views/shopfloor_menu.xml
index 868dc85c6c..12143b931c 100644
--- a/shopfloor/views/shopfloor_menu.xml
+++ b/shopfloor/views/shopfloor_menu.xml
@@ -168,6 +168,16 @@
/>
+
+
+
+