From e08ad600b4676d80cba0766d5b7f22966f82314c Mon Sep 17 00:00:00 2001 From: Thierry Ducrest Date: Fri, 3 Nov 2023 08:46:40 +0100 Subject: [PATCH] shopfloor: add checkout option ask leaf location dest Following this change on the checkout scenario https://github.com/OCA/wms/pull/618 A check has been added to force the user to scan a child location if the destination location is not a leaf in the locations tree. To allow for flexibility this change adds the options to disable this feature. --- shopfloor/README.rst | 2 +- shopfloor/__manifest__.py | 2 +- shopfloor/data/shopfloor_scenario_data.xml | 3 +- .../migrations/14.0.4.4.0/post-migration.py | 41 +++++++++++++++++++ shopfloor/models/shopfloor_menu.py | 20 +++++++++ shopfloor/services/checkout.py | 13 +++--- shopfloor/static/description/index.html | 2 +- shopfloor/tests/test_checkout_done.py | 17 ++++++++ shopfloor/views/shopfloor_menu.xml | 10 +++++ 9 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 shopfloor/migrations/14.0.4.4.0/post-migration.py diff --git a/shopfloor/README.rst b/shopfloor/README.rst index fc45976e59..baa0cc03fc 100644 --- a/shopfloor/README.rst +++ b/shopfloor/README.rst @@ -7,7 +7,7 @@ Shopfloor !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:f1d165021abc730bc8bf96092b9f76139e4b17c777975af4c9e496f86774bab6 + !! source digest: sha256:b2c51fbfe37b326cc86b4856116825c4ccc2692b607ab630ac8e5a1e0baf5173 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/shopfloor/__manifest__.py b/shopfloor/__manifest__.py index 24f053bf1b..69d181623a 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.3.1", + "version": "14.0.4.4.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.4.4.0/post-migration.py b/shopfloor/migrations/14.0.4.4.0/post-migration.py new file mode 100644 index 0000000000..3d8a75e15f --- /dev/null +++ b/shopfloor/migrations/14.0.4.4.0/post-migration.py @@ -0,0 +1,41 @@ +# 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 01b8b6c81b..9494bb1c76 100644 --- a/shopfloor/services/checkout.py +++ b/shopfloor/services/checkout.py @@ -1405,13 +1405,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/static/description/index.html b/shopfloor/static/description/index.html index a6c2c6c887..b34913d754 100644 --- a/shopfloor/static/description/index.html +++ b/shopfloor/static/description/index.html @@ -367,7 +367,7 @@

Shopfloor

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:f1d165021abc730bc8bf96092b9f76139e4b17c777975af4c9e496f86774bab6 +!! source digest: sha256:b2c51fbfe37b326cc86b4856116825c4ccc2692b607ab630ac8e5a1e0baf5173 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/wms Translate me on Weblate Try me on Runboat

Shopfloor is a barcode scanner application for internal warehouse operations.

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 @@ /> + + + +