diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index e2ff5909110..351c7d2351e 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.3.5.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 f01317981d7..3e00842dc7a 100644 --- a/shopfloor/data/shopfloor_scenario_data.xml +++ b/shopfloor/data/shopfloor_scenario_data.xml @@ -44,7 +44,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 00000000000..71359aa01b7 --- /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 d411bbb738a..7ac80b6bf0c 100644 --- a/shopfloor/models/shopfloor_menu.py +++ b/shopfloor/models/shopfloor_menu.py @@ -46,6 +46,11 @@ decreasing the delivered quantity of the related SO line. """ +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" @@ -211,6 +216,14 @@ class ShopfloorMenu(models.Model): auto_post_line_is_possible = fields.Boolean( compute="_compute_auto_post_line_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): @@ -432,3 +445,10 @@ def _compute_allow_alternative_destination_is_possible(self): def _compute_allow_return_is_possible(self): for menu in self: menu.allow_return_is_possible = menu.scenario_id.has_option("allow_return") + + @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 14e9592b626..7847efd7b80 100644 --- a/shopfloor/services/checkout.py +++ b/shopfloor/services/checkout.py @@ -1381,13 +1381,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 a9acce20322..ccd2b173c25 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 e69266b8f25..3f0bcf8e5bc 100644 --- a/shopfloor/views/shopfloor_menu.xml +++ b/shopfloor/views/shopfloor_menu.xml @@ -158,6 +158,16 @@ + + + +