From dd2cdfc87330e52f2657b7561e7d7f0efc9aaf80 Mon Sep 17 00:00:00 2001 From: Michael Tietz Date: Mon, 4 Dec 2023 12:29:05 +0100 Subject: [PATCH 1/9] [ADD] shopfloor_full_location_reservation: Full location reservation for shopfloor --- .../README.rst | 85 ++++ .../__init__.py | 3 + .../__manifest__.py | 24 + shopfloor_full_location_reservation/hooks.py | 17 + .../models/__init__.py | 1 + .../models/shopfloor_menu.py | 27 ++ .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 1 + .../services/__init__.py | 2 + .../services/location_content_transfer.py | 28 ++ .../services/zone_picking.py | 41 ++ .../static/description/index.html | 424 ++++++++++++++++++ .../tests/__init__.py | 1 + .../tests/test_shopfloor_scenario.py | 15 + .../views/shopfloor_menu.xml | 18 + 15 files changed, 689 insertions(+) create mode 100644 shopfloor_full_location_reservation/README.rst create mode 100644 shopfloor_full_location_reservation/__init__.py create mode 100644 shopfloor_full_location_reservation/__manifest__.py create mode 100644 shopfloor_full_location_reservation/hooks.py create mode 100644 shopfloor_full_location_reservation/models/__init__.py create mode 100644 shopfloor_full_location_reservation/models/shopfloor_menu.py create mode 100644 shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst create mode 100644 shopfloor_full_location_reservation/readme/DESCRIPTION.rst create mode 100644 shopfloor_full_location_reservation/services/__init__.py create mode 100644 shopfloor_full_location_reservation/services/location_content_transfer.py create mode 100644 shopfloor_full_location_reservation/services/zone_picking.py create mode 100644 shopfloor_full_location_reservation/static/description/index.html create mode 100644 shopfloor_full_location_reservation/tests/__init__.py create mode 100644 shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py create mode 100644 shopfloor_full_location_reservation/views/shopfloor_menu.xml diff --git a/shopfloor_full_location_reservation/README.rst b/shopfloor_full_location_reservation/README.rst new file mode 100644 index 00000000000..82ce737d48f --- /dev/null +++ b/shopfloor_full_location_reservation/README.rst @@ -0,0 +1,85 @@ +=================================== +Shopfloor full location reservation +=================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:35d8955934ffa87167ab48b3e318cc821dd786633e011e6e5a0e7ca6bd190b21 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github + :target: https://github.com/OCA/wms/tree/14.0/shopfloor_full_location_reservation + :alt: OCA/wms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-shopfloor_full_location_reservation + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Adds a configuration to the shopfloor scenario which allows to trigger the stock full location reservation + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* MT Software + +Contributors +~~~~~~~~~~~~ + +* Michael Tietz (MT Software) +* Jacques-Etienne Baudoux (BCIM) + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-mt-software-de| image:: https://github.com/mt-software-de.png?size=40px + :target: https://github.com/mt-software-de + :alt: mt-software-de + +Current `maintainer `__: + +|maintainer-mt-software-de| + +This module is part of the `OCA/wms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/shopfloor_full_location_reservation/__init__.py b/shopfloor_full_location_reservation/__init__.py new file mode 100644 index 00000000000..6f585eb890b --- /dev/null +++ b/shopfloor_full_location_reservation/__init__.py @@ -0,0 +1,3 @@ +from . import models +from . import services +from .hooks import post_init_hook diff --git a/shopfloor_full_location_reservation/__manifest__.py b/shopfloor_full_location_reservation/__manifest__.py new file mode 100644 index 00000000000..25c4a6e5218 --- /dev/null +++ b/shopfloor_full_location_reservation/__manifest__.py @@ -0,0 +1,24 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Shopfloor full location reservation", + "summary": ( + "Adds a configuration to the shopfloor scenario " + "which allows to trigger the stock full location reservation" + ), + "author": "MT Software, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/wms", + "category": "Warehouse Management", + "version": "14.0.1.0.0", + "license": "AGPL-3", + "depends": [ + "shopfloor", + "stock_full_location_reservation", + ], + "data": [ + "views/shopfloor_menu.xml", + ], + "auto_install": True, + "post_init_hook": "post_init_hook", + "maintainers": ["mt-software-de"], +} diff --git a/shopfloor_full_location_reservation/hooks.py b/shopfloor_full_location_reservation/hooks.py new file mode 100644 index 00000000000..df7574c06b1 --- /dev/null +++ b/shopfloor_full_location_reservation/hooks.py @@ -0,0 +1,17 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import json + +from odoo import SUPERUSER_ID, api + + +def post_init_hook(cr, registry): + env = api.Environment(cr, SUPERUSER_ID, {}) + + for scenario in [ + env.ref("shopfloor.scenario_location_content_transfer"), + env.ref("shopfloor.scenario_zone_picking"), + ]: + options = scenario.options + options["full_location_reservation"] = True + scenario.options_edit = json.dumps(options) diff --git a/shopfloor_full_location_reservation/models/__init__.py b/shopfloor_full_location_reservation/models/__init__.py new file mode 100644 index 00000000000..8bd3d5195ca --- /dev/null +++ b/shopfloor_full_location_reservation/models/__init__.py @@ -0,0 +1 @@ +from . import shopfloor_menu diff --git a/shopfloor_full_location_reservation/models/shopfloor_menu.py b/shopfloor_full_location_reservation/models/shopfloor_menu.py new file mode 100644 index 00000000000..6ba4cdc2d58 --- /dev/null +++ b/shopfloor_full_location_reservation/models/shopfloor_menu.py @@ -0,0 +1,27 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class ShopfloorMenu(models.Model): + _inherit = "shopfloor.menu" + + full_location_reservation_is_possible = fields.Boolean( + compute="_compute_full_location_reservation_is_possible" + ) + full_location_reservation = fields.Boolean( + string="Process full location reservation", + default=False, + help=( + "If you tick this box, a full location reservation " + "is triggered for each move_lines location which was found." + ), + ) + + @api.depends("scenario_id") + def _compute_full_location_reservation_is_possible(self): + for menu in self: + menu.full_location_reservation_is_possible = menu.scenario_id.has_option( + "full_location_reservation" + ) diff --git a/shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst b/shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..03c3145a2be --- /dev/null +++ b/shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Michael Tietz (MT Software) +* Jacques-Etienne Baudoux (BCIM) diff --git a/shopfloor_full_location_reservation/readme/DESCRIPTION.rst b/shopfloor_full_location_reservation/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..193b816aec0 --- /dev/null +++ b/shopfloor_full_location_reservation/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Adds a configuration to the shopfloor scenario which allows to trigger the stock full location reservation diff --git a/shopfloor_full_location_reservation/services/__init__.py b/shopfloor_full_location_reservation/services/__init__.py new file mode 100644 index 00000000000..14596c94346 --- /dev/null +++ b/shopfloor_full_location_reservation/services/__init__.py @@ -0,0 +1,2 @@ +from . import location_content_transfer +from . import zone_picking diff --git a/shopfloor_full_location_reservation/services/location_content_transfer.py b/shopfloor_full_location_reservation/services/location_content_transfer.py new file mode 100644 index 00000000000..a65090d5228 --- /dev/null +++ b/shopfloor_full_location_reservation/services/location_content_transfer.py @@ -0,0 +1,28 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.addons.component.core import Component + + +class LocationContentTransfer(Component): + _inherit = "shopfloor.location.content.transfer" + + def _find_location_move_lines_from_scan_location(self, *args, **kwargs): + move_lines = super()._find_location_move_lines_from_scan_location( + *args, **kwargs + ) + if not self.work.menu.full_location_reservation: + return move_lines + + if any(move_lines.move_id.mapped("is_full_location_reservation")): + return move_lines + + move_lines |= move_lines.move_id._full_location_reservation().move_line_ids + return move_lines.exists() + + def _move_lines_cancel_work(self, move_lines): + res = super()._move_lines_cancel_work(move_lines) + if not self.work.menu.full_location_reservation: + return res + move_lines.move_id.undo_full_location_reservation() + return res diff --git a/shopfloor_full_location_reservation/services/zone_picking.py b/shopfloor_full_location_reservation/services/zone_picking.py new file mode 100644 index 00000000000..290d20071e0 --- /dev/null +++ b/shopfloor_full_location_reservation/services/zone_picking.py @@ -0,0 +1,41 @@ +# Copyright 2023 Michael Tietz (MT Software) +# Copyright 2023 Jacques-Etienne Baudoux (BCIM) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo.addons.component.core import Component + + +class ZonePicking(Component): + _inherit = "shopfloor.zone.picking" + + def _handle_full_location_package_reservation(self, package): + return package and self.work.menu.full_location_reservation + + def _handle_complete_mix_pack(self, package): + """Return true if full location reservation is enabled + otherwise if there is not more than one product on the package + it will return False + """ + if self._handle_full_location_package_reservation(package): + return True + return super()._handle_complete_mix_pack(package) + + def _set_destination_location( + self, move_line, package, quantity, confirmation, location + ): + if self._handle_full_location_package_reservation(package): + move_line._full_location_reservation(package_only=True) + # Ensure all move lines have the same destination package. + # If moves lines are in different pickings, the destination package + # is not set in standard + # a stock.package_level is only created if all products of the package + # are contained in the picking + move_line.search( + [ + ("package_id", "=", package.id), + ("state", "in", ("partially_available", "assigned")), + ("result_package_id", "!=", package.id), + ] + ).result_package_id = package + return super()._set_destination_location( + move_line, package, quantity, confirmation, location + ) diff --git a/shopfloor_full_location_reservation/static/description/index.html b/shopfloor_full_location_reservation/static/description/index.html new file mode 100644 index 00000000000..61de65e0e95 --- /dev/null +++ b/shopfloor_full_location_reservation/static/description/index.html @@ -0,0 +1,424 @@ + + + + + + +Shopfloor full location reservation + + + +
+

Shopfloor full location reservation

+ + +

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

+

Adds a configuration to the shopfloor scenario which allows to trigger the stock full location reservation

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • MT Software
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

mt-software-de

+

This module is part of the OCA/wms project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/shopfloor_full_location_reservation/tests/__init__.py b/shopfloor_full_location_reservation/tests/__init__.py new file mode 100644 index 00000000000..7c7964fc87d --- /dev/null +++ b/shopfloor_full_location_reservation/tests/__init__.py @@ -0,0 +1 @@ +from . import test_shopfloor_scenario diff --git a/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py b/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py new file mode 100644 index 00000000000..c0a8f2f02f4 --- /dev/null +++ b/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py @@ -0,0 +1,15 @@ +# Copyright 2023 Michael Tietz (MT Software) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.addons.shopfloor_base.tests.common import CommonCase + + +class TestShopfloorScenario(CommonCase): + @classmethod + def setUpClassUsers(cls): + super().setUpClassUsers() + cls.env = cls.env(user=cls.shopfloor_manager) + + def test_scenario(self): + scenario = self.env.ref("shopfloor.scenario_location_content_transfer") + self.assertTrue(scenario.options["full_location_reservation"]) diff --git a/shopfloor_full_location_reservation/views/shopfloor_menu.xml b/shopfloor_full_location_reservation/views/shopfloor_menu.xml new file mode 100644 index 00000000000..f39b8e513fe --- /dev/null +++ b/shopfloor_full_location_reservation/views/shopfloor_menu.xml @@ -0,0 +1,18 @@ + + + + shopfloor.menu + + + + + + + + + + + From 96dde10706c3ce962f0a08c4263b4529eebae896 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 6 Dec 2023 17:41:30 +0100 Subject: [PATCH 2/9] [IMP] shopfloor_full_location_reservation: pre-commit stuff --- .../odoo/addons/shopfloor_full_location_reservation | 1 + setup/shopfloor_full_location_reservation/setup.py | 6 ++++++ .../tests/test_shopfloor_scenario.py | 1 + 3 files changed, 8 insertions(+) create mode 120000 setup/shopfloor_full_location_reservation/odoo/addons/shopfloor_full_location_reservation create mode 100644 setup/shopfloor_full_location_reservation/setup.py diff --git a/setup/shopfloor_full_location_reservation/odoo/addons/shopfloor_full_location_reservation b/setup/shopfloor_full_location_reservation/odoo/addons/shopfloor_full_location_reservation new file mode 120000 index 00000000000..b45b0d1a4d5 --- /dev/null +++ b/setup/shopfloor_full_location_reservation/odoo/addons/shopfloor_full_location_reservation @@ -0,0 +1 @@ +../../../../shopfloor_full_location_reservation \ No newline at end of file diff --git a/setup/shopfloor_full_location_reservation/setup.py b/setup/shopfloor_full_location_reservation/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/shopfloor_full_location_reservation/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py b/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py index c0a8f2f02f4..7ab0b62de74 100644 --- a/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py +++ b/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py @@ -4,6 +4,7 @@ from odoo.addons.shopfloor_base.tests.common import CommonCase +# pylint: disable=missing-return class TestShopfloorScenario(CommonCase): @classmethod def setUpClassUsers(cls): From 8c27cf4f0fad040514160f783942c7576a06df70 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 6 Dec 2023 17:57:08 +0100 Subject: [PATCH 3/9] [16.0][MIG] shopfloor_full_location_reservation --- shopfloor_full_location_reservation/README.rst | 13 +++++++------ shopfloor_full_location_reservation/__manifest__.py | 2 +- .../readme/CONTRIBUTORS.rst | 1 + .../services/zone_picking.py | 4 ++-- .../static/description/index.html | 9 +++++---- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/shopfloor_full_location_reservation/README.rst b/shopfloor_full_location_reservation/README.rst index 82ce737d48f..3451b99981d 100644 --- a/shopfloor_full_location_reservation/README.rst +++ b/shopfloor_full_location_reservation/README.rst @@ -7,7 +7,7 @@ Shopfloor full location reservation !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:35d8955934ffa87167ab48b3e318cc821dd786633e011e6e5a0e7ca6bd190b21 + !! source digest: sha256:3307576cc4eec247d9fa4544c58c07e3a3f1d086d7c2d96b0488abba42cdfd66 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -17,13 +17,13 @@ Shopfloor full location reservation :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwms-lightgray.png?logo=github - :target: https://github.com/OCA/wms/tree/14.0/shopfloor_full_location_reservation + :target: https://github.com/OCA/wms/tree/16.0/shopfloor_full_location_reservation :alt: OCA/wms .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/wms-14-0/wms-14-0-shopfloor_full_location_reservation + :target: https://translation.odoo-community.org/projects/wms-16-0/wms-16-0-shopfloor_full_location_reservation :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=14.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/wms&target_branch=16.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -41,7 +41,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -58,6 +58,7 @@ Contributors * Michael Tietz (MT Software) * Jacques-Etienne Baudoux (BCIM) +* Denis Roussel Maintainers ~~~~~~~~~~~ @@ -80,6 +81,6 @@ Current `maintainer `__: |maintainer-mt-software-de| -This module is part of the `OCA/wms `_ project on GitHub. +This module is part of the `OCA/wms `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/shopfloor_full_location_reservation/__manifest__.py b/shopfloor_full_location_reservation/__manifest__.py index 25c4a6e5218..50fd39c430b 100644 --- a/shopfloor_full_location_reservation/__manifest__.py +++ b/shopfloor_full_location_reservation/__manifest__.py @@ -9,7 +9,7 @@ "author": "MT Software, Odoo Community Association (OCA)", "website": "https://github.com/OCA/wms", "category": "Warehouse Management", - "version": "14.0.1.0.0", + "version": "16.0.1.0.0", "license": "AGPL-3", "depends": [ "shopfloor", diff --git a/shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst b/shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst index 03c3145a2be..866de0e85cb 100644 --- a/shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst +++ b/shopfloor_full_location_reservation/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Michael Tietz (MT Software) * Jacques-Etienne Baudoux (BCIM) +* Denis Roussel diff --git a/shopfloor_full_location_reservation/services/zone_picking.py b/shopfloor_full_location_reservation/services/zone_picking.py index 290d20071e0..fda1bf687af 100644 --- a/shopfloor_full_location_reservation/services/zone_picking.py +++ b/shopfloor_full_location_reservation/services/zone_picking.py @@ -20,7 +20,7 @@ def _handle_complete_mix_pack(self, package): return super()._handle_complete_mix_pack(package) def _set_destination_location( - self, move_line, package, quantity, confirmation, location + self, move_line, package, quantity, confirmation, location, barcode ): if self._handle_full_location_package_reservation(package): move_line._full_location_reservation(package_only=True) @@ -37,5 +37,5 @@ def _set_destination_location( ] ).result_package_id = package return super()._set_destination_location( - move_line, package, quantity, confirmation, location + move_line, package, quantity, confirmation, location, barcode ) diff --git a/shopfloor_full_location_reservation/static/description/index.html b/shopfloor_full_location_reservation/static/description/index.html index 61de65e0e95..e72516462db 100644 --- a/shopfloor_full_location_reservation/static/description/index.html +++ b/shopfloor_full_location_reservation/static/description/index.html @@ -367,9 +367,9 @@

Shopfloor full location reservation

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:35d8955934ffa87167ab48b3e318cc821dd786633e011e6e5a0e7ca6bd190b21 +!! source digest: sha256:3307576cc4eec247d9fa4544c58c07e3a3f1d086d7c2d96b0488abba42cdfd66 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

+

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

Adds a configuration to the shopfloor scenario which allows to trigger the stock full location reservation

Table of contents

@@ -388,7 +388,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -404,6 +404,7 @@

Contributors

@@ -415,7 +416,7 @@

Maintainers

promote its widespread use.

Current maintainer:

mt-software-de

-

This module is part of the OCA/wms project on GitHub.

+

This module is part of the OCA/wms project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

From 1beb6e0756960fe576ff5127e8c15e4822bc953c Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 10 Jun 2024 16:15:26 +0200 Subject: [PATCH 4/9] [FIX] shopfloor_full_location_reservation: Don't do the full reservation on move but on move line As a stock move can point to several move lines on several stock locations, don't do the full reservation process on move but on lines. --- .../services/location_content_transfer.py | 2 +- .../tests/test_shopfloor_scenario.py | 94 +++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/shopfloor_full_location_reservation/services/location_content_transfer.py b/shopfloor_full_location_reservation/services/location_content_transfer.py index a65090d5228..a646d922557 100644 --- a/shopfloor_full_location_reservation/services/location_content_transfer.py +++ b/shopfloor_full_location_reservation/services/location_content_transfer.py @@ -17,7 +17,7 @@ def _find_location_move_lines_from_scan_location(self, *args, **kwargs): if any(move_lines.move_id.mapped("is_full_location_reservation")): return move_lines - move_lines |= move_lines.move_id._full_location_reservation().move_line_ids + move_lines |= move_lines._full_location_reservation().move_line_ids return move_lines.exists() def _move_lines_cancel_work(self, move_lines): diff --git a/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py b/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py index 7ab0b62de74..aadbe5918f8 100644 --- a/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py +++ b/shopfloor_full_location_reservation/tests/test_shopfloor_scenario.py @@ -1,6 +1,9 @@ # Copyright 2023 Michael Tietz (MT Software) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo.addons.shopfloor.tests.test_location_content_transfer_base import ( + LocationContentTransferCommonCase, +) from odoo.addons.shopfloor_base.tests.common import CommonCase @@ -14,3 +17,94 @@ def setUpClassUsers(cls): def test_scenario(self): scenario = self.env.ref("shopfloor.scenario_location_content_transfer") self.assertTrue(scenario.options["full_location_reservation"]) + + +class LocationContentTransferFull(LocationContentTransferCommonCase): + """ + Tests for Stock Content Transfer in Full Reservation context + + * /set_destination_line + + """ + + @classmethod + def setUpClassBaseData(cls): + super().setUpClassBaseData() + cls.picking = cls._create_picking( + lines=[(cls.product_a, 10), (cls.product_b, 5.0)] + ) + cls.picking.picking_type_id.sudo().merge_move_for_full_location_reservation = ( + True + ) + defaults = { + "location_id": cls.picking.location_id.id, + "name": "Sub location 1", + "barcode": "SUBLOCATION1", + } + cls.sub_location_1 = cls.picking.location_id.sudo().copy(defaults) + defaults = { + "location_id": cls.picking.location_id.id, + "name": "Sub location 2", + "barcode": "SUBLOCATION2", + } + cls.sub_location_2 = cls.picking.location_id.sudo().copy(defaults) + defaults = { + "location_id": cls.picking.location_id.id, + "name": "Sub location 3", + "barcode": "SUBLOCATION3", + } + cls.sub_location_3 = cls.picking.location_id.sudo().copy(defaults) + + cls._update_qty_in_location(cls.sub_location_1, cls.product_a, 5) + # Set more quantities on sub location 2 to trigger a move creation + cls._update_qty_in_location(cls.sub_location_2, cls.product_a, 10) + cls._update_qty_in_location(cls.sub_location_3, cls.product_b, 5) + # Reserve quantities + cls.picking.action_assign() + # cls._simulate_pickings_selected(cls.picking) + cls.dest_location = ( + cls.env["stock.location"] + .sudo() + .create( + { + "name": "Sub Shelf 1", + "barcode": "subshelf1", + "location_id": cls.shelf1.id, + } + ) + ) + + def test_scan_location_assignation(self): + """ + Test case: + + - Product A is present in several sub location of 'Stock': + - Sub location 1 : 5.0 + - Sub location 2 : 10.0 + - Product B is present in sub location 3 (5.0) + + When scanning the location origin for product A (in sub location 1), + the + """ + self.menu.sudo().full_location_reservation = True + self.service.dispatch("scan_location", params={"barcode": "SUBLOCATION1"}) + move_a_after = self.env["stock.move"].search( + [ + ("product_id", "=", self.product_a.id), + ("state", "=", "assigned"), + ("picking_id", "!=", self.picking.id), + ] + ) + + self.assertEqual("assigned", self.picking.state) + + # Check the move have been changed to a new picking + move_a = self.picking.move_ids.filtered( + lambda move: move.product_id == self.product_a + ) + self.assertNotEqual(move_a, move_a_after) + + self.assertEqual(1, len(move_a_after.move_line_ids)) + + self.assertEqual(5.0, move_a.product_uom_qty) + self.assertEqual(5.0, move_a_after.product_uom_qty) From bcaf027b79a2c86abb948c2d98555aec0dac34d9 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Fri, 12 Jul 2024 16:23:46 +0200 Subject: [PATCH 5/9] [IMP] shopfloor_full_location_reservation: Code compatibility with PR #917 _find_location_move_lines_from_scan_location method has been renamed into _select_move_lines_first_location --- .../services/location_content_transfer.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/shopfloor_full_location_reservation/services/location_content_transfer.py b/shopfloor_full_location_reservation/services/location_content_transfer.py index a646d922557..f9bc13622c1 100644 --- a/shopfloor_full_location_reservation/services/location_content_transfer.py +++ b/shopfloor_full_location_reservation/services/location_content_transfer.py @@ -7,10 +7,8 @@ class LocationContentTransfer(Component): _inherit = "shopfloor.location.content.transfer" - def _find_location_move_lines_from_scan_location(self, *args, **kwargs): - move_lines = super()._find_location_move_lines_from_scan_location( - *args, **kwargs - ) + def _select_move_lines_first_location(self, move_lines): + move_lines = super()._select_move_lines_first_location(move_lines) if not self.work.menu.full_location_reservation: return move_lines From 4f19f3f00acdf8d3c4cde04e6e28b502046bbbee Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 21 Aug 2024 14:41:56 +0200 Subject: [PATCH 6/9] [IMP] shopfloor_full_location_reservation: Filter lines with one location As after full reservation, returned lines could concern several source locations, we need to filter them one more time for the first location --- .../services/location_content_transfer.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shopfloor_full_location_reservation/services/location_content_transfer.py b/shopfloor_full_location_reservation/services/location_content_transfer.py index f9bc13622c1..421e430bf1d 100644 --- a/shopfloor_full_location_reservation/services/location_content_transfer.py +++ b/shopfloor_full_location_reservation/services/location_content_transfer.py @@ -8,14 +8,18 @@ class LocationContentTransfer(Component): _inherit = "shopfloor.location.content.transfer" def _select_move_lines_first_location(self, move_lines): - move_lines = super()._select_move_lines_first_location(move_lines) if not self.work.menu.full_location_reservation: - return move_lines + return super()._select_move_lines_first_location(move_lines) if any(move_lines.move_id.mapped("is_full_location_reservation")): - return move_lines + return super()._select_move_lines_first_location(move_lines) + move_lines = super()._select_move_lines_first_location(move_lines) move_lines |= move_lines._full_location_reservation().move_line_ids + + # As lines should concern only one source location and as lines + # can have been split, we need to retrieve only those with first location + move_lines = super()._select_move_lines_first_location(move_lines.exists()) return move_lines.exists() def _move_lines_cancel_work(self, move_lines): From 0ec7c004714d35cef9a952ccd7f87022cbed359a Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Wed, 4 Sep 2024 19:15:58 +0200 Subject: [PATCH 7/9] [IMP] shopfloor_full_location_reservation: Use strict mode for full reservation --- .../services/location_content_transfer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shopfloor_full_location_reservation/services/location_content_transfer.py b/shopfloor_full_location_reservation/services/location_content_transfer.py index 421e430bf1d..2a2139d9b14 100644 --- a/shopfloor_full_location_reservation/services/location_content_transfer.py +++ b/shopfloor_full_location_reservation/services/location_content_transfer.py @@ -15,7 +15,7 @@ def _select_move_lines_first_location(self, move_lines): return super()._select_move_lines_first_location(move_lines) move_lines = super()._select_move_lines_first_location(move_lines) - move_lines |= move_lines._full_location_reservation().move_line_ids + move_lines |= move_lines._full_location_reservation(strict=True).move_line_ids # As lines should concern only one source location and as lines # can have been split, we need to retrieve only those with first location From 3bf3e2ca90ae14dca8eb76185ccc0663886a862d Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Wed, 24 Jun 2026 10:48:52 +0200 Subject: [PATCH 8/9] [IMP] shopfloor_full_location_reservation: Uses new 'reservation_mode' parameter' --- .../services/location_content_transfer.py | 4 +++- shopfloor_full_location_reservation/services/zone_picking.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/shopfloor_full_location_reservation/services/location_content_transfer.py b/shopfloor_full_location_reservation/services/location_content_transfer.py index 2a2139d9b14..60b144ef12b 100644 --- a/shopfloor_full_location_reservation/services/location_content_transfer.py +++ b/shopfloor_full_location_reservation/services/location_content_transfer.py @@ -15,7 +15,9 @@ def _select_move_lines_first_location(self, move_lines): return super()._select_move_lines_first_location(move_lines) move_lines = super()._select_move_lines_first_location(move_lines) - move_lines |= move_lines._full_location_reservation(strict=True).move_line_ids + move_lines |= move_lines._full_location_reservation( + reservation_mode="strict" + ).move_line_ids # As lines should concern only one source location and as lines # can have been split, we need to retrieve only those with first location diff --git a/shopfloor_full_location_reservation/services/zone_picking.py b/shopfloor_full_location_reservation/services/zone_picking.py index fda1bf687af..1ad4a6c46ca 100644 --- a/shopfloor_full_location_reservation/services/zone_picking.py +++ b/shopfloor_full_location_reservation/services/zone_picking.py @@ -23,7 +23,7 @@ def _set_destination_location( self, move_line, package, quantity, confirmation, location, barcode ): if self._handle_full_location_package_reservation(package): - move_line._full_location_reservation(package_only=True) + move_line._full_location_reservation(reservation_mode="package") # Ensure all move lines have the same destination package. # If moves lines are in different pickings, the destination package # is not set in standard From f688b6651fd661083fe6af5b398109e14ea7d78d Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Tue, 23 Jun 2026 08:38:46 +0200 Subject: [PATCH 9/9] [DO NOT MERGE] --- test-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test-requirements.txt b/test-requirements.txt index 689482e20df..b474e571663 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,2 +1,3 @@ vcrpy-unittest odoo_test_helper +odoo-addon-stock-full-location-reservation @ git+https://github.com/OCA/wms.git@refs/pull/1194/head#subdirectory=setup/stock_full_location_reservation